未触发飞行前请求以进行CORS检查 [英] Pre-flight Request not triggered for CORS check

查看:163
本文介绍了未触发飞行前请求以进行CORS检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,如果以下任何一种情况为 false ,浏览器就会发送飞行前请求(来源:

As I understand, a pre-flight request is sent by the browser if any of the following conditions is false (source: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests):

  • 请求方法是GET,HEAD或POST.
  • 未设置自定义标题.
  • Content-Type标头值是application/x-www-form-urlencodedmultipart/form-datatext/plain.
  • Request method is GET, HEAD or POST.
  • Custom headers are not set.
  • Content-Type header value is either application/x-www-form-urlencoded, multipart/form-data or text/plain.

我有一个Web应用程序,该应用程序将GET请求发送到其他来源的服务器.由于必须将cookie发送到服务器,因此属性withCredentials设置为true.标头Content-Type设置为application/json.对于此请求,浏览器不会触发飞行前请求,但应这样做,因为第三个条件为假.这可能是什么原因?

I have a web app which sends a GET request to a server on a different origin. Since I have to send cookies to the server, the property withCredentials is set to true. The header Content-Type is set to application/json. For this request, the browser does not trigger a pre-flight request, but it should because the third condition is false. What could be the reason behind this? Does it have anything to do with the insignificance of Content-Type header for a GET request (since there is no request body)?

添加请求代码:

configObject = {
  'withCredentials': true,
  headers: {
    'Content-Type': 'application/json'
  }
};

function getRequest(url, dict) {
  $http.get(url, Object.assign({}, configObject)).success(function(result) {
    // on success
  }).error(function(err) {
    // on error
  });
  // return
}

推荐答案

如果您的前端代码正在发起跨域请求,而发出请求的代码实际上将Content-Type标头设置为application/json,则绝对会触发浏览器进行预检.总是.

If your frontend code is initiating a cross-origin request and the code making the request actually sets the Content-Type header to application/json, then that’ll absolutely trigger the browser to do a preflight. Always.

因此,在该问题中,这意味着未触发浏览器进行预检是因为实际上并未将标头添加到浏览器最终发送的请求中.

So that means, in the case in the question, the reason the browser isn’t getting triggered to do a preflight is that the header isn’t actually getting added to the request the browser ends up sending.

但是问题中描述的特殊情况是……奇怪–因为它试图将Content-Type标头添加到 GET请求和问题中的GET请求(例如几乎所有其他GET请求)都没有请求正文.

But the particular case described in the question is… odd — because it’s trying to add a Content-Type header to a GET request, and the GET request in the question (like pretty much all other GET requests) doesn’t have a request body.

因此,在这种情况下,原因是Angular在进行$http调用时会自动执行某种可以说是很聪明的操作(如果出现意外情况):如果没有请求正文,它将删除Content-Type请求中的标头-这很有道理,因为如果没有请求正文,则无需指定标头的媒体类型.

And so what the cause comes down to in this case is that Angular, for $http calls, automatically does something arguably kind of smart (if unexpected): In the absence of a request body, it removes the Content-Type header from the request — which makes some good sense, because if there’s no request body, there’s no need to have a header specifying its media type.

角度,内容类型不会与$ http 一起发送以确认这一点.

See the accepted answer at Angular, content type is not being sent with $http for confirmation of that.

因此,如果由于某种原因您确实需要在没有请求主体的请求中包含Content-Type标头,则解决方案是根本不使用Angular的$http,而是使用例如标准Fetch API,即使没有请求主体的请求,它也允许您包含Content-Type;否则(如果您还需要使用Angular的$http的某些要求)将空请求主体作为该请求的一部分传递$http请求(通过在请求中添加data: '').

And so, if for some reason you really need to include the Content-Type header in a request having no request body, then the solution is either to not use Angular’s $http at all — and instead use, say, the standard Fetch API, which will allow you to include the Content-Type even for requests lacking a request body — or else (in case you also have some requirement to use Angular’s $http) to pass in an empty request body as part of the $http request (by adding data: '' to the request).

这篇关于未触发飞行前请求以进行CORS检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆