世界杯2022是哪个国家_国足世界杯出线 - dtfyjq.com

  • 首页
  • 北京世界杯
  • 世界杯新秀
  • 世界杯16强名单

最新发表

  • priority什么意思、怎么读?单词用法、记忆法、发音音标、反义词同义词辨析、释义
  • ajax网站有哪些
  • 狗狗刨地是什么意思?了解狗狗这一行为背后的原因与心理
  • 梦幻西游手游时空区可以卡69吗?全面解析卡级系统
  • [笑死]中国足球搞笑段子、经典笑话综合榜单!
  • 请教各位怎么给LG的三个法宝补充灵气?
  • 荥的拼音、荥怎么读?草字头加秃宝盖下一个水(艹冖水)念什么?
  • 詹姆斯加入美国国家队:为世界最佳篮球实力再添助力
  • IE浏览器是英文版怎么办
  • 科龙空调和格力哪个好

友情链接

Copyright © 2022 世界杯2022是哪个国家_国足世界杯出线 - dtfyjq.com All Rights Reserved.

理解 CORS、预检请求 (Preflight) 和跨域

世界杯16强名单 · 2025-09-23 12:57:55

这篇主要来聊一聊前端常见的跨域问题,以及后端如何处理 CORS 和预检请求 (Preflight)。

浏览器在什么情况下会发生跨域浏览器通过“同源策略”限制不同源之间的资源交互,以保护用户隐私和安全。其中源由三个部分组成:协议、域名 和 端口。只有这三者同时满足才是同源。否则,就是跨域,向服务端发送请求时会触发浏览器的跨域限制,报以下错误:

TEXTAccess to fetch at 'https://server.suemor.com/api/posts' from origin 'https://suemor.com' CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.具体看下方 4 个例子。

跨域以下是三种跨域情况:

不同协议HTTPhttps://suemor.com

http://suemor.com/api/posts不同域名HTTPhttps://suemor.com

https://server.suemor.com/api/posts

//tips: 下方这个也是跨域

http://127.0.0.1:3000 -> http://localhost:3000/api/posts不同端口HTTPhttp://localhost:3000

http://localhost:5050/api/posts同源下方这个是同源,没有跨域问题。

HTTPhttps://suemor.com

https://suemor.com/api/posts解决跨域跨域问题通常在服务端解决,通过配置反向代理或修改后端代码。

跨域请求分为简单请求和复杂请求:

简单请求对于同时满足以下三个条件的即为简单请求,服务器只需返回正确的 CORS 头,即 Access-Control-Allow-Origin:

请求方法:GET、POST 或 HEAD。Content-Type:限于 application/x-www-form-urlencoded、multipart/form-data 或 text/plain。不包含自定义头:如 Authorization。看以下 Express 示例:

TYPESCRIPT// 假设 web 端位于 http://localhost:3000

// 假设 server 端位于 http://localhost:5050

// web

fetch("http://localhost:5000/api/posts", { method: "GET" });

// server

app.use((req: Request, res: Response, next: NextFunction) => {

res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); // 或者 res.setHeader("Access-Control-Allow-Origin", "");

next();

});复杂请求符合以下任意一条,即为复杂请求:

使用 PUT、DELETE 、PATCH 方法。Content-Type: application/json。包含自定义请求头(如 Authorization)。复杂请求比较特殊,浏览器会先发送一个 OPTIONS 方法的预检请求(Preflight),检查服务器是否允许该跨域请求。如果不允许,则直接抛出 CORS 错误,不再发送实际请求。

CORS 错误

因此,我们需要单独处理这个预检请求(Preflight):

TYPESCRIPT// 假设 web 端位于 http://localhost:3000

// 假设 server 端位于 http://localhost:5050

// web

fetch("http://localhost:5050/api/data", {

method: "PUT",

headers: {

"Content-Type": "application/json",

Authorization: "Bearer token",

},

body: JSON.stringify({ data: "example" }),

});

// server

app.use((req: Request, res: Response, next: NextFunction) => {

res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");

if (req.method === "OPTIONS") {

res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");

res.header("Access-Control-Allow-Methods", "PUT");

res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");

res.status(200).end();

return;

}

next();

});设置 Access-Control-Max-Age复杂请求在无缓存或缓存失效时会发送两次请求:Preflight(OPTIONS)和实际请求,这会增加网络开销。为此,服务器可以通过设置 Access-Control-Max-Age 响应头来控制浏览器缓存预检结果的时长。这个头字段的值表示缓存的有效期(以秒为单位)。在缓存有效期内,浏览器会复用之前的预检结果,跳过对相同接口的 Preflight 请求,从而提升性能。

TYPESCRIPTres.header('Access-Control-Max-Age', '86400'); // 缓存 1 天支持跨域 Cookie 的配置在跨域场景下,如果后端响应头返回 Set-Cookie,默认不会生效,因为设置 Cookie 需要额外配置以绕过浏览器的安全限制。核心是启用 Access-Control-Allow-Credentials 并明确指定 Access-Control-Allow-Origin。以下是一个 Express 示例:

TYPESCRIPTapp.use((req: Request, res: Response, next: NextFunction) => {

res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); // 一定要指定具体地址,不能为 *

res.setHeader("Access-Control-Allow-Credentials", "true"); //添加这个

if (req.method === "OPTIONS") {

res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");// 一定要指定具体地址,不能为 *

res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");

res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");

res.setHeader("Access-Control-Max-Age", "86400");

res.status(200).end();

return;

}

next();

});

app.post("/api/posts", (req: Request, res: Response) => {

res.cookie("sessionId", "123456789", {

httpOnly: true,

secure: process.env.NODE_ENV === "production",

sameSite: "none",

maxAge: 24 * 60 * 60 * 1000,

});

res.json({ success: true, message: "Cookie set" });

});注意这里 Access-Control-Allow-Origin 一定要指定具体的地址,不能设置为 Access-Control-Allow-Origin: *,否则 Cookie 无效。

前端如果使用 fetch 调用,则一定要加上 credentials: "include"否则无法设置 Cookie。如果是 axios 则加上 withCredentials: true。

TYPESCRIPT//fetch

fetch("http://localhost:5050/api/posts", {

method: "POST",

credentials: "include", // 允许携带和接收 Cookie

}).then((res) => res.json());

//axios

axios({

url: "http://localhost:5050/api/posts",

method: "POST",

withCredentials: true, // 允许携带和接收 Cookie

})

.then((res) => res.data)

.catch((err) => console.error(err));


最新肆拾玖坊价格表一览 53度肆拾玖坊酒价格
上海探秘:揭秘本地热门的“找鸡”好去处