![](/img/trans.png)
[英]React+Express: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response
[英]“Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response” despite valid CORS config
我使用 Google Cloud Functions 创建了一个 API 端点,并试图从 JS 获取 function 调用它。
我遇到了我很确定与 CORS 或 output 格式有关的错误,但我不确定发生了什么。 其他一些 SO 问题类似,并帮助我意识到我需要删除mode: "no-cors"
。 大多数人提到在 BE 上启用 CORS,所以我添加了response.headers.set('Access-Control-Allow-Origin', '*')
- 我在本文中了解到 - 以确保 CORS 将被启用......但是我仍然收到“无法获取”错误。
完整错误(可在下面链接的现场演示中重现)是:
未捕获的错误:无法添加节点 1,因为具有该 ID 的节点已在 Store 中。 (这个大概是无关的吧? )
从源“https://o2gxx.csb.app”访问“https://us-central1-stargazr-ncc-2893.cloudfunctions.net/nearest_csc?lat=37.75&lon=-122.5”获取已被阻止CORS 策略:请求 header 字段 access-control-allow-origin 在预检响应中被 Access-Control-Allow-Headers 不允许。
GET https://us-central1-stargazr-ncc-2893.cloudfunctions.net/nearest_csc?lat=37.75&lon=-122.5 net::ERR_FAILED
Uncaught (in promise) TypeError: Failed to fetch
请参阅下面的代码片段,请注意我在哪里使用<---- *** Message ***
来表示最近更改的代码部分,这给了我这两个错误之一。
前端代码:
function getCSC() {
let lat = 37.75;
let lng = -122.5;
fetch(
`https://us-central1-stargazr-ncc-2893.cloudfunctions.net/nearest_csc?lat=${lat}&lon=${lng}`,
{
method: "GET",
// mode: "no-cors", <---- **Uncommenting this predictably gets rid of CORS error but returns a Opaque object which seems to have no data**
headers: {
// Accept: "application/json", <---- **Originally BE returned stringified json. Not sure if I should be returning it as something else or if this is still needed**
Origin: "https://lget3.csb.app",
"Access-Control-Allow-Origin": "*"
}
}
)
.then(response => {
console.log(response);
console.log(response.json());
});
}
后端代码:
import json
import math
import os
import flask
def nearest_csc(request):
"""
args: request object w/ args for lat/lon
returns: String, either with json representation of nearest site information or an error message
"""
lat = request.args.get('lat', type = float)
lon = request.args.get('lon', type = float)
# Get list of all csc site locations
with open(file_path, 'r') as f:
data = json.load(f)
nearby_csc = []
# Removed from snippet for clarity:
# populate nearby_csc (list) with sites (dictionaries) as elems
# Determine which site is the closest, assigned to var 'closest_site'
# Grab site url and return site data if within 100 km
if dist_km < 100:
closest_site['dist_km'] = dist_km
// return json.dumps(closest_site) <--- **Original return statement. Added 4 lines below in an attempt to get CORS set up, but did not seem to work**
response = flask.jsonify(closest_site)
response.headers.set('Access-Control-Allow-Origin', '*')
response.headers.set('Access-Control-Allow-Methods', 'GET, POST')
return response
return "No sites found within 100 km"
上面代码片段的更完整上下文:
我还想知道 CodeSandbox 是否有可能以一种奇怪的方式执行 CORS ,但是在localhost:3000
上运行它时遇到了同样的问题,当然在 prod 中会在我自己的个人域中使用它。
该错误似乎与 CORS 相关( 'https://o2gxx.csb.app' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
)但我认为添加response.headers.set('Access-Control-Allow-Origin', '*')
可以解决这个问题。 我需要在 BE 上更改其他内容吗? 在FE上?
TLDR;
即使在尝试在后端启用 CORS 并将标头添加到 FE 之后,我仍然收到错误“无法获取”和“访问控制允许标头不允许字段访问控制允许来源”。 有关代码的实时演示,请参见上面的链接。
删除添加Access-Control-Allow-Origin
请求 header 的前端代码部分。
切勿在前端 JavaScript 代码中添加Access-Control-Allow-Origin
作为请求 header。
唯一的影响是负面的,因为它会导致浏览器执行 CORS 预检OPTIONS
请求,即使来自前端代码的实际( GET
, POST
等)请求不会触发预检。 然后预检将失败并显示以下消息:
预检响应中的 Access-Control-Allow-Headers 不允许请求 header 字段 Access-Control-Allow-Origin
…也就是说,除非请求的服务器已配置为发送Access-Control-Allow-Headers: Access-Control-Allow-Origin
响应 header,否则它将失败。
但是您永远不需要 Access-Control Access-Control-Allow-Headers
Access-Control-Allow-Origin
。 如果这最终使事情正常进行,那么您实际上只是在解决错误的问题。 因为真正的解决方法是:永远不要将Access-Control-Allow-Origin
设置为请求 header。
直观地说,将其视为“我在请求和响应中都设置了Access-Control-Allow-Origin
,因此这应该比仅在响应中包含它更好”似乎是合乎逻辑的——但实际上比仅在响应中设置它更糟糕(出于上述原因)。
所以底线: Access-Control-Allow-Origin
只是响应 header,而不是请求 header。 所以你只想在服务器端响应代码中设置它,而不是前端 JavaScript 代码。
问题中的代码还试图添加一个Origin
header。 您也永远不想尝试在您的前端 JavaScript 代码中设置 header。
Unlike the case with the Access-Control-Allow-Origin
header, Origin
is actually a request header — but it's a special header that's controlled completely by browsers, and browsers won't ever allow your frontend JavaScript code to set it. 所以永远不要尝试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.