服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - js教程 - 一日一技:Next.js如何正确处理跨域问题?

一日一技:Next.js如何正确处理跨域问题?

2024-01-29 17:28未闻Code js教程

去年下半年接手了一个基于React + Next.js的项目,于是顺带学习了一下Next.js。由于Next.js的特点,这个项目的前后端是放在一起的。一开始没什么问题,看了半天文档就上手了。

我以前一直使用Vue来写前端。去年下半年接手了一个基于React + Next.js的项目,于是顺带学习了一下Next.js。由于Next.js的特点,这个项目的前后端是放在一起的。一开始没什么问题,看了半天文档就上手了。

上周我们需要在另一个网页项目中,调用这个项目的后端接口,于是就需要处理跨域请求的问题。但我发现按照网上的方法,跨域问题依然存在。这个问题浪费了我不少时间,好在最后终于找到了原因。记录在这里,免得大家跟我一样踩坑。

为了复现这个问题,我们先来创建一个Next.js项目。执行代码创建代码脚手架:

npx create-next-app test_cors

使用TypeScript,其他选项选择默认,如下图所示:

一日一技:Next.js如何正确处理跨域问题?图片

命令执行完成以后,会生成一个test_cors文件夹,在文件夹中创建文件pages/api/test.ts。内容如下:

import { NextResponse } from 'next/server'


export const config = {
    runtime: "edge"
}

export interface UserInfo {
    name: string
    age: number
    address: string
}


const handler = async (req: Request): Promise<Response> => {
    
    const user = (await req.json()) as UserInfo
    return NextResponse.json({success: true,
                              msg: `你的名字是${user.name}, 今年${user.age}岁`})
}

export default handler;

如下图所示:

一日一技:Next.js如何正确处理跨域问题?图片

然后运行命令npm run dev。这个后端接口就启动起来了。我们可以使用Postman来进行测试:

一日一技:Next.js如何正确处理跨域问题?图片

接下来,我们来写一段HTML代码,触发跨域问题:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>API 请求示例</title>
    <script>
        // 当按钮被点击时执行此函数
        function sendRequest() {
            // 创建一个新的 XMLHttpRequest 对象
            var xhr = new XMLHttpRequest();

            // 配置请求类型、URL 以及异步处理
            xhr.open('POST', 'http://127.0.0.1:3000/api/test', true);

            // 设置请求头
            xhr.setRequestHeader('Content-Type', 'application/json');
            // ... 其他请求头设置

            // 设置响应类型
            xhr.responseType = 'json';

            // 定义请求完成的回调函数
            xhr.onload = function () {
                if (xhr.status === 200) {
                    // 请求成功,处理响应数据
                    document.getElementById('response').innerText = JSON.stringify(xhr.response);
                } else {
                    // 请求失败,处理错误
                    document.getElementById('response').innerText = '请求失败: ' + xhr.status;
                }
            };

            // 发送请求
            xhr.send(JSON.stringify({name: "青南", age: 20, "address": "上海"}));
        }
    </script>
</head>
<body>
    <button onclick="sendRequest()">发送请求</button>
    <div id="response"></div>
</body>
</html>

直接双击打开这个html文件,点击页面上的按扭,就会触发跨域报错,如下图所示:

一日一技:Next.js如何正确处理跨域问题?图片

然后,你在网上用关键词搜索next.js 跨域或者next.js cors,一般看到的文章都会让你直接在next.config.js文件中添加响应头,如下图所示:

一日一技:Next.js如何正确处理跨域问题?图片

你按照这些文章中写到方法加了配置,重启服务,然后用Postman来测试,你会发现返回的响应头里面确实已经有这几项了,如下图所示:

一日一技:Next.js如何正确处理跨域问题?图片

但当你使用HTML页面来测试时,跨域的报错还在。

你连续打开Google上面10篇讲Next.js跨域的文章,无论是中文博客还是英文博客,甚至你直接使用ChatGPT来问,他们给你的回复肯定都是上面的这个方法。但是无论你怎么测试,跨域问题还在。

实际上,跨域就是这样配置的。你的配置没有任何问题。问题出现在你的后端代码上,如下图所示:

一日一技:Next.js如何正确处理跨域问题?图片

首先你需要是一个POST请求,你才能执行await req.json()。而浏览器在判断能不能跨域时,会首先发送一个OPTIONS请求,如下图所示:

一日一技:Next.js如何正确处理跨域问题?图片

这个请求也会走到你的这段后端代码里面。但由于OPTIONS请求没有Body,于是代码运行到await req.json()时,就会报错。于是浏览器认为OPTIONS请求没有返回status 200,因此强行认为你的接口不支持跨域。

那么解决方法也非常简单,提前判断一下请求方法是不是OPTIONS就可以了:

if(req.method === 'OPTIONS') {
    return NextResponse.next()
}

如下图所示:

一日一技:Next.js如何正确处理跨域问题?图片

运行效果如下图所示,跨域成功:

一日一技:Next.js如何正确处理跨域问题?图片

这个问题对于资深前端来说,可能不值一提。但对于后端兼职前端的人,或者第一次接触Next.js的人来说,可能是一个深坑,会浪费很多的时间。

原文地址:https://mp.weixin.qq.com/s/Npjlb2HqphjVjjkK7GF19g

延伸 · 阅读

精彩推荐
  • js教程微信小程序抽奖组件的使用步骤

    微信小程序抽奖组件的使用步骤

    这篇文章主要给大家介绍了关于微信小程序抽奖组件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需...

    い 狂奔的蜗牛11072021-12-29
  • js教程JavaScript实现前端倒计时效果

    JavaScript实现前端倒计时效果

    这篇文章主要为大家详细介绍了JavaScript实现前端倒计时效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    L在前方4342022-01-20
  • js教程五种使 JavaScript 代码库更干净的方法

    五种使 JavaScript 代码库更干净的方法

    今天向大家介绍5种使JavaScript代码库更干净的方法,一起来看一下都有哪些吧!...

    Mason程10822021-12-29
  • js教程js canvas实现圆形流水动画

    js canvas实现圆形流水动画

    这篇文章主要为大家详细介绍了js canvas实现圆形流水动画,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    莫兮是我11092022-03-06
  • js教程JS canvas实现画板和签字板功能

    JS canvas实现画板和签字板功能

    这篇文章主要为大家详细介绍了JS canvas实现画板和签字板功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    莫兮是我10772022-01-22
  • js教程一篇文章看懂JavaScript中的回调

    一篇文章看懂JavaScript中的回调

    这篇文章主要给大家介绍了如何通过一篇文章看懂JavaScript中的回调,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    疯狂的技术宅4872021-12-27
  • js教程js实现拖拽拼图游戏

    js实现拖拽拼图游戏

    这篇文章主要为大家详细介绍了js实现拖拽拼图游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    一个学前端的小菜鸟11672022-01-12
  • js教程mapboxgl实现带箭头轨迹线的代码

    mapboxgl实现带箭头轨迹线的代码

    这篇文章主要介绍了mapboxgl实现带箭头轨迹线的代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    GIS兵器库9572021-12-27