Javascript 飞行前请求与所有方法一起发送
我的FE应用程序正在使用来自不同域的API。我知道它应该触发CORS,但据我所知,它不应该为每个请求创建预飞行 根据,我不应该对Javascript 飞行前请求与所有方法一起发送,javascript,angular,cors,preflight,Javascript,Angular,Cors,Preflight,我的FE应用程序正在使用来自不同域的API。我知道它应该触发CORS,但据我所知,它不应该为每个请求创建预飞行 根据,我不应该对GET方法发出飞行前请求 Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if: - It uses methods other than
GET
方法发出飞行前请求
Cross-site requests are preflighted like this since they may have implications to
user data. In particular, a request is preflighted if:
- It uses methods other than GET, HEAD or POST.
Also, if POST is used to send request data with a Content-Type
other than application/x-www-form-urlencoded, multipart/form-data,
or text/plain, e.g. if the POST request sends an XML payload to the
server using application/xml or text/xml, then the request is preflighted.
- It sets custom headers in the request
(e.g. the request uses a header such as X-PINGOTHER)
然而,我发送的每一个请求都有飞行前(选项)请求,不管是GET还是POST,我发现这很奇怪(根据docs的说法)
我设置了一些标题(我将使用凭据发送它:true
),但我不认为这应该是问题所在:
headers.append('Access-Control-Allow-Origin', FRONTEND_URL);
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/json');
headers.append('Authorization', this._generateApiKey());
headers.append('Language', this._languageISOCode);
我遗漏了什么吗?看到了吗
CORS飞行前选项
请求只需在请求中添加内容类型
标题即可触发-如果值不是应用程序/x-www-form-urlencoded
、文本/普通
或多部分/表单数据
。即使对于GET
请求也是如此(尽管您永远不应该向GET
添加内容类型的头-因为没有请求主体,所以它没有任何用途)
在问题中显示的标题中,授权
标题也会触发预飞行,“语言
”标题(甚至不是标准标题名称;可能是接受语言
?)和访问控制允许源代码
标题也会触发预飞行(它甚至不是一个请求头;它是一个响应头,不应该在前端代码中使用)
对于不触发预飞行的头:Fetch规范(定义CORS行为)指定它调用的,它定义为:
接受
接受语言
内容语言
内容类型
的值在解析后具有MIME类型(忽略参数),即应用程序/x-www-form-urlencoded
、多部分/表单数据
或文本/普通
任何请求(包括任何GET
请求)如果包含不在上述CORS安全列表请求头中的头,将触发预飞行
为了让这一切变得更清楚,我更新了和(它比上面描述的稍微复杂一些,实际上,但上面的内容足以说明这个问题的上下文)
请注意,WebKit/Safari对Accept
、Accept Language
和Content Language
标题中允许的值设置了额外的限制
如果其中任何一个标题具有“非标准”值,WebKit/Safari将进行预飞行
至于WebKit/Safari认为这些头文件的“非标准”值,除了以下WebKit bug之外,没有真正的文档记录:
没有其他浏览器实现这些额外的限制,因为它们不是规范的一部分。它们是在没有与规范编辑器或其他浏览器进行任何讨论的情况下单方面添加到WebKit的。跨域问题通常发生在应用程序托管在一个域上,web服务托管在另一个域上,而我们尝试进行Ajax调用以获得响应。
对web服务的Ajax调用以CORS错误结束。调用的HTTP方法是OPTIONS,而不是GET或POST
解决这个问题是一个方面,但我们仍然需要保留安全身份验证。否则,我们将最终暴露一个未经验证的web服务,这是一个威胁
if (request.getMethod().equals("OPTIONS") && request.getHeader(ORIGIN).equals(FRONTEND_URL))
{
response.setHeader("Access-Control-Allow-Origin", FRONTEND_URL);
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, HEAD");
response.setHeader("Access-Control-Allow-Headers",request.getHeader("Access-Control-Request-Headers"));
}
WithCredentials是您的自定义标头,这意味着它会为GET/POST请求预飞行。这不是CORS安全列出的请求标头-您的意思是它不在您显示的4个标头列表中吗?是的,任何不在上述4个标头列表中的标头。