前端、node跨域问题

发布于:2025-09-03 ⋅ 阅读:(20) ⋅ 点赞:(0)

前端页面访问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+)


网站公告

今日签到

点亮在社区的每一天
去签到