jQuery 如何使用授权标头发出 GET CORS 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25064158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 11:02:01  来源:igfitidea点击:

How to make GET CORS request with authorization header

jqueryajaxdjangoapachecors

提问by Matija

I was reading about CORS requests, and I have managed to make regular GET or POST request and it works fine. But when I add authorization header to a either GET or POST request, then the preflight OPTIONS request is sent to the server and I get 500 INTERNAL SERVER ERR, and the actual request isn't sent. My question is how does the preflight actually work, and what response does it require so that it will send the main request? And is it possible to send it without the preflight because I'm sure that then it would work? The serve-rside is written in Django 1.6 and has ACCESS-ALLOW-ORIGIN set to *, and it works with regular post and get requests.

我正在阅读有关 CORS 请求的信息,并且我设法进行了常规的 GET 或 POST 请求,并且工作正常。但是,当我向 GET 或 POST 请求添加授权标头时,预检选项请求被发送到服务器,我得到 500 INTERNAL SERVER ERR,实际请求没有发送。我的问题是预检实际上是如何工作的,它需要什么响应才能发送主要请求?是否可以在没有预检的情况下发送它,因为我确定它会起作用?server-rside 是用 Django 1.6 编写的,并且将 ACCESS-ALLOW-ORIGIN 设置为 *,它可以处理常规的 post 和 get 请求。

This is my JS code:

这是我的JS代码:

 $.ajax({
  type: "GET",
  url: "http://url/login/",
  async:false,
  contentType: "application/json",
  headers: {
    "Authorization": "Basic " + btoa(loginName + ':' + password),       
  },
  success: function (data) {
    alert("OK!");
  },
  failure: function(errMsg) {
    alert(errMsg);
  }
});

These are the headers from Chrome DevTools when the request is executed: Request headers:

这些是执行请求时来自 Chrome DevTools 的标头: 请求标头:

OPTIONS /login/ HTTP/1.1
Host: url
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)     Chrome/36.0.1985.125 Safari/537.36
Access-Control-Request-Headers: accept, authorization, content-type
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,hr;q=0.6,sr;q=0.4

Response headers:

响应头:

HTTP/1.1 500 INTERNAL SERVER ERROR
Date: Thu, 31 Jul 2014 16:15:19 GMT
Server: Apache/2.2.15 (CentOS)
X-Frame-Options: SAMEORIGIN
Access-Control-Allow-Origin: *
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

回答by J0HN

To pass authorization headers you must set Access-Control-Allow-Credentialsto true.

要传递授权标头,您必须设置Access-Control-Allow-Credentials为 true。

The problem is that, according to specification (MDN explains it simpler), if Access-Control-Allow-Credentialsis set to true, Access-Control-Allow-Origincannot contain *, therefore allowing any hosts making requests with credentials attached.

问题是,根据规范(MDN 解释得更简单),如果Access-Control-Allow-Credentials设置为 true,Access-Control-Allow-Origin则不能包含*,因此允许任何主机发出附加凭据的请求。

There are two options to solve this problem:

有两种选择可以解决这个问题:

  • Set Access-Control-Allow-Originto actual host making requests
  • If there are more than one host: "canonical" way would be to have a whitelist of hosts in application itself, than check Originheader if it's on the list and adding Originas Access-Control-Allow-Originheader value.
  • 设置Access-Control-Allow-Origin为实际主机发出请求
  • 如果有多个主机:“规范”方式是在应用程序本身中包含主机白名单,而不是检查Origin标头是否在列表中并添加OriginAccess-Control-Allow-Origin标头值。

With Django, check for Originand adding a header can be made in Middleware, but that would make a decent question on it's own (and probably have been already asked)

使用 Django,Origin可以在中间件中检查和添加标头,但这本身就是一个不错的问题(并且可能已经被问到)