当前位置: 首页 > news >正文

Next.js如何正确处理跨域问题?

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

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

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

npx create-next-app test_cors

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

图片

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

import { NextResponse } from 'next/server'export const config = {runtime: "edge"
}export interface UserInfo {name: stringage: numberaddress: string
}const handler = async (req: Request): Promise<Response> => {const user = (await req.json()) as UserInforeturn NextResponse.json({success: true,msg: `你的名字是${user.name}, 今年${user.age}岁`})
}export default handler;

如下图所示:

图片

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

图片

接下来,我们来写一段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 cors,一般看到的文章都会让你直接在next.config.js文件中添加响应头,如下图所示:

图片

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

图片

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

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

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

图片

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

图片

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

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

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

如下图所示:

图片

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

图片

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

相关文章:

  • 网络ADB连接(不用实体安卓线)
  • 每日一练:LeeCode-404、左叶子之和【二叉树】
  • IDEA:git 回滚本地提交-git 选择 Reset Current Branch to
  • 《区块链简易速速上手小册》第4章:区块链与加密货币(2024 最新版)
  • Vue2:请求接口的两种方式axios和vue-resource
  • 大模型重塑车载语音交互:赛道巨头如何引领新周期?
  • 力扣0114——二叉树展开为链表
  • Python爬虫请求库安装
  • Spring Cloud使用笔记
  • 判断一个字符串中出现次数最多的字符,统计这个次数?
  • C++——特殊类
  • Flink 添加 / 部署 Jar 包的若干注意事项
  • Python与CAD系列高级篇(二十五)分类提取坐标到excel(补充圆半径、线长度、圆弧)
  • ES6 模块化、CommonJS 模块化的区别经典面试题
  • 【网络协议测试】畸形数据包——圣诞树攻击(DOS攻击)
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【React系列】如何构建React应用程序
  • crontab执行失败的多种原因
  • css属性的继承、初识值、计算值、当前值、应用值
  • extract-text-webpack-plugin用法
  • HTTP--网络协议分层,http历史(二)
  • JavaWeb(学习笔记二)
  • js写一个简单的选项卡
  • LeetCode29.两数相除 JavaScript
  • Logstash 参考指南(目录)
  • MobX
  • PHP的Ev教程三(Periodic watcher)
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • 近期前端发展计划
  • 利用jquery编写加法运算验证码
  • 配置 PM2 实现代码自动发布
  • 前端面试之CSS3新特性
  • 区块链将重新定义世界
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 使用 QuickBI 搭建酷炫可视化分析
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 我有几个粽子,和一个故事
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • 昨天1024程序员节,我故意写了个死循环~
  • ​Java基础复习笔记 第16章:网络编程
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • ### RabbitMQ五种工作模式:
  • ###STL(标准模板库)
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • (1)Nginx简介和安装教程
  • (层次遍历)104. 二叉树的最大深度
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (三) diretfbrc详解
  • (三)docker:Dockerfile构建容器运行jar包
  • (微服务实战)预付卡平台支付交易系统卡充值业务流程设计
  • (一)项目实践-利用Appdesigner制作目标跟踪仿真软件
  • (转)memcache、redis缓存