前端、node跨域问题

前端页面访问node后端接口跨域报错

Access to XMLHttpRequest at 'http://192.18.31.75/api/get?name=ss\&age=19' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这个报错的意思是:你的前端页面(http://127.0.0.1:5500)在请求后端接口(http://192.18.31.75/api/get)时,因为跨域被浏览器拦截了。

原因:

  • 浏览器的同源策略限制了不同源(协议、域名、端口不同)的请求。

  • 后端没有设置 Access-Control-Allow-Origin 响应头,浏览器就会阻止前端访问数据。


解决方法

1. 在 Express 后端允许跨域

安装 cors 中间件:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
npm install cors

在你的 app.js 里添加如下代码:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
const cors = require("cors");
app.use(cors());//需要写在路由注册之前

//有其他配置的写法
app.use(cors({
  allowedHeaders: ["Content-Type", "Authorization", "token"]
}));

这样所有接口都允许跨域访问。


2. 手动设置响应头(不推荐,推荐用 cors)

2.1 cors响应 Access-Control-Allow-Origin

手动设置响应头:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");//*也可写成其他具体网站
  next();
});

使用 cors 中间件(推荐):

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
const cors = require("cors");
app.use(cors()); // 默认允许所有来源,自动设置 Access-Control-Allow-Origin: *
//或者
const cors = require("cors");
app.use(cors({
  origin: "http://127.0.0.1:5500" // 只允许这个来源跨域
}));

2.2 cors响应头,Access-Control-Allow-Headers

是 CORS(跨域资源共享)中的一个响应头,用于指定允许哪些自定义请求头可以在跨域请求中使用。

cors仅支持客户端向服务器发送9个请求头,如果客户向服务器发送了额外的请求头信息,则需要在服务端,通过Access-Control-Allow-Headers对额外的请求头声明

手动设置响应头:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
//允许客户端额外向服务器发送Content-Type请求头和X-Custom-Header请求头
res.setHeader('Access-Control-Allow-Headers','Content-Type','X-Custom-Header')
res.setHeader("Access-Control-Allow-Origin", "*");

使用 cors 中间件(推荐):

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
const cors = require("cors");
app.use(cors({
  allowedHeaders: ["Content-Type", "Authorization", "token"]
}));

2.3 cors响应头,Access-Control-Allow-Methods

Access-Control-Allow-Methods 是 CORS(跨域资源共享)中的一个响应头,用于指定允许哪些 HTTP 方法可以进行跨域请求

作用:

当浏览器发起跨域请求时,如果请求方法不是简单的 GET/POST/HEAD,或者有自定义头部,会先发送一个预检请求(OPTIONS)。服务器需要通过 Access-Control-Allow-Methods 告诉浏览器:哪些方法(如 GET、POST、PUT、DELETE 等)是被允许的。

常见用法:

手动设置响应头:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
  next();
});

使用 cors 中间件(推荐):

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
const cors = require("cors");
app.use(cors({
  methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
}));

3.jsonp

JSONP 用于解决跨域问题。 callback 是前端指定的回调函数名,后端用它把数据"包裹"起来返回,前端通过这个函数获取数据。

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
//前端写法
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 引入jquery线上版 -->
    <script src="https://cdn.staticfile.net/jquery/3.7.1/jquery.min.js"></script>
  </head>
  <body>
    <button id="btnjsonp">测试jsonp</button>
    <script>
      $(function () {
        //jQuery 会自动生成类似 jQuery371013504642194028282_1754319071541 的回调名,并带到请求里。
        $("#btnjsonp").on("click", function () {
          $.ajax({
            type: "GET",
            url: "http://192.18.31.75:80/api/jsonp",
            dataType: "jsonp",
            success: function (res) {
              console.log(res, "res");
            },
          });
        });
      });
    </script>
  </body>
</html>

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
//node后端router.js文件
const express = require("express");
const apiRouter = express.Router();
//jsonp
// JSONP 用于解决跨域问题。
// callback 是前端指定的回调函数名,后端用它把数据"包裹"起来返回,前端通过这个函数获取数据。
apiRouter.get("/jsonp", (req, res) => {
  // 这是因为你用 jQuery 的 $.ajax 或 $.getJSON 发起了 JSONP 请求,jQuery 会自动生成一个全局唯一的回调函数名(防止冲突),并把它作为 callback 参数传给后端。
  // 后端收到请求后,把数据包裹在这个函数名里返回,前端就能通过这个函数拿到数据
  const funcName = req.query.callback;
  console.log("funcName", funcName); //打印结果:funcName jQuery371013504642194028282_1754319071541
  const data = { name: "zz", age: 11 };
  const scriptStr = `${funcName}(${JSON.stringify(data)})`;
  res.send(scriptStr);
});
module.exports = apiRouter;


//app.js文件内容
const express = require("express");
const router = require("./router");
const cors = require("cors");//cors可以不用写
const app = express();

app.use(cors());//cors可以不用写
app.use(express.urlencoded({ extended: false }));
app.use("/api", router);

app.listen(80, () => {
  console.log("express server running at http://192.18.31.75");
});

总结:

只要后端加上 CORS 相关响应头,前端就能正常跨域访问接口了。推荐使用 cors 中间件,简单安全。

备注:注意:主要在服务器端进行配置,客户端无需做任何配置。cors在浏览器中有兼容性,只有支持XMLHttpRequest Level2的浏览器,才能正常的访问开了cors的服务端接口(例如:IE10+ Chrom4+ FireFox3.5+)

相关推荐
Yang961118 分钟前
一台顶三台:鼎讯DLJ-1在不同故障类型中的模式切换数据复盘
服务器·网络·数据库
潘正翔23 分钟前
Memcached构建缓存服务器
运维·服务器·数据库·缓存·云原生·memcached
NineData34 分钟前
NineData 与平凯数据库(TiDB 企业版)完成产品兼容性互认证
数据库·tidb·ninedata·玖章算术·平凯数据库·产品兼容性认证·tidb企业版
咖啡星人k44 分钟前
2026 Text-to-SQL:一句话让 AI 写 SQL,自然语言直接查数据库(MonkeyCode 云端实战)
数据库·机器学习·语言模型·自然语言处理
GreatSQL社区1 小时前
少敲一个字母,GreatSQL 对所有查询“已读不回”
数据库·mysql·greatsql
wangchunyu1141 小时前
PostgreSQL 入门与实践:从零搭建一个 CRUD 应用
数据库·postgresql
涛思数据(TDengine)1 小时前
从_找根因_到_搭系统_:工业 AI 实战直播(十、十一期)
大数据·数据库·人工智能·时序数据库·tdengine
qq_339191143 小时前
mysql磁盘占用排查,mysql存储空间占比统计,mysql判断哪张表占用磁盘空间大
数据库·mysql
东方护航数据恢复(深圳)3 小时前
SSD主控损坏后的芯片级提取:FTL映射表重建与NAND直读
大数据·数据库