JS fetch 无法设置标题

Posted

技术标签:

【中文标题】JS fetch 无法设置标题【英文标题】:JS fetch unable to set headers 【发布时间】:2021-09-13 20:56:24 【问题描述】:

我有一个连接到 Spring Boot 后端应用程序的反应应用程序,我使用 JWT 在后端授权用户。我正在使用 fetch 在前端和后端之间进行调用。

每当我尝试设置调用的标头时,所有标头都会被删除,包括 Cookie(其中包含 JWT)。我需要设置标头来指定请求的内容类型。

- 当我没有设置标题时调用(导致 415)

获取代码:

return fetch(`$urlApiGateway$url`, 
    method: "POST",
    body: body,
    credentials: "include",
)

呼叫:

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,nl-NL;q=0.8,nl;q=0.7
Connection: keep-alive
Content-Length: 13
content-type: text/plain;charset=UTF-8
Cookie: Authorization=Bearer_eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJjYXNwZXIubS50b3JlbjJAZ21haWwuY29tIiwiZXhwIjoxNjI1NDg2MzAzLCJpYXQiOjE2MjUzOTk5MDMsInVzZXIiOnsiaWQiOjIsIm5hbWUiOiJjYXNwZXIiLCJlbWFpbCI6ImNhc3Blci5tLnRvcmVuMkBnbWFpbC5jb20iLCJwYXNzd29yZCI6IiIsInBlcm1pc3Npb25zIjoiQURNSU4ifX0.JdW1M7d8HB71yvP7dupomN-bgD_484HHbxmfnOOmvqM
Host: localhost:8080
Origin: http://localhost:3000
Referer: http://localhost:3000/
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/91.0.4472.124 Safari/537.36

如您所见,标题显示为“content-type”和“Cookie”。

- 当我设置标题以防止 415 时调用

获取代码:

return fetch(`$urlApiGateway$url`, 
    method: "POST",
    body: body,
    headers:  "Content-Type": "application/json" ,
    credentials: "include",
)

呼叫:

似乎在进行 4 次调用,2 次与之前的 fetch 设置相同(没有设置标题)。

其中 2 个调用如下所示

Provisional headers are shown
content-type: application/json
Referer: http://localhost:3000/
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36

和 2 看起来像这样

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,nl-NL;q=0.8,nl;q=0.7
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: localhost:8080
Origin: http://localhost:3000
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36

如您所见,标头已消失,包括 Cookie 和内容类型。

- 弹簧靴子

@Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowedOrigins(allowOrigin, "http://localhost:3000")
                .allowCredentials(true)
                .allowedHeaders("*")
                .allowedMethods("GET", "POST", "OPTIONS");
    

希望有人能帮忙:)

【问题讨论】:

请将文字作为文字发布,而不是文字图片。 好的,将编辑它 【参考方案1】:

您必须将 Authorization Bearer 令牌作为标头传递。试试这个:

let yourAuthToken = .... // get bearer token from where you store it

return fetch(`$urlApiGateway$url`, 
    method: "POST",
    body: body,
    headers: 
      'Authorization' : 'Bearer ' + yourAuthToken
    
)

【讨论】:

我不能这样做,因为我将令牌设置为 HttpOnly 以防止跨站点脚本。由于某种原因,添加标题也不起作用。【参考方案2】:

这与 js 代码没有任何关系,这是我在后端的 cors 设置。我的授权过滤器也被应用于导致 cors 错误(没有 http ok 状态)的 OPTIONS 请求,更改后它已修复。

感谢所有试图帮助我的人。

【讨论】:

以上是关于JS fetch 无法设置标题的主要内容,如果未能解决你的问题,请参考以下文章

Safari 不使用 JS Fetch API 设置 CORS cookie

Fetch API 无法加载“.php”本地文件 - React JS + PHP

为啥 PHP 无法从 Js FormData fetch 中获取 $_POST 数据?

使用带有模式的 fetch API:'no-cors',无法设置请求标头

设置 chromium depot_tools 时无法运行 fetch android

无法使用 fetch API 获取数据