【问题标题】:JQuery preflight request CORSJQuery 预检请求 CORS
【发布时间】:2018-11-19 08:30:08
【问题描述】:

我正在编写一个网络地图并尝试从我确实有凭据的网络资源中获取 JSON。这在通过 JuPyteR 笔记本运行的 Python 中效果很好:

import requests
header = {  "Accept": "application/json, text/plain, */*",
        "Accept-Language": "de-DE",
        "Content-Type": "application/json",
        "Pragma": "no-cache",
        "Cache-Control": "no-cache",
        "Origin": "https://myCoolServer.azurewebsites.net"}
}
dataJSON = json.dumps({ "username": "XXX",
    "password": "XXX"}).encode('utf8')
url = "URL/v1/token"
r = requests.post(url, data=dataJSON, headers=header)

来自 python 的请求给出以下标头:

'User-Agent': 'python-requests/2.19.1', 
'Accept-Encoding': 'gzip, deflate', 
'Accept': 'application/json, text/plain, */*', 
'Connection': 'keep-alive', 
'Accept-Language': 'de-DE', 
'Content-Type': 'application/json', 
'Pragma': 'no-cache', 
'Cache-Control': 'no-cache', 
'Content-Length': '67',
'Origin': 'https://myCoolServer.azurewebsites.net'

现在我正在尝试在 JavaScript 中重新创建它以在我的网络地图中获取数据:

$.ajax ({
          method: 'POST',
          data: JSON.stringify({ "username": name,
    "password": pass}),
    headers:  {
        "Accept": "application/json, text/plain, */*",
        "Accept-Language": "de-DE",
        "Content-Type": "application/json",
        "Pragma": "no-cache",
        "Cache-Control": "no-cache"
      },
          dataType:'json',
          url:'URL/v1/token',
          error: function() {
            alert("Login failed. Check username/password!");
          },
          success: function(resp) {

            token=resp.token;
          }

控制台显示预检选项调用的以下标头:

Host: "cool API"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-DE
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: POST
Access-Control-Request-Headers: cache-control,content-type,pragma
Origin: https://myCoolServer.azurewebsites.net
DNT: 1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

根据 200 响应,来自服务器的预检选项响应是成功的。然而,我没有完成 POST,因为 FF 和 Chrome 中的控制台给了我:

Origin https://myCoolServer.azurewebsites.net not found in Access-Control-Allow-Origin header.

来自服务器的响应标头给了我:

HTTP/1.1 200 OK
Date: Mon, 19 Nov 2018 08:07:30 GMT
Server: Apache/2.4.18 (Ubuntu)
Cache-Control: no-cache, private
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, PUT, GET, DELETE, OPTIONS
Access-Control-Allow-Headers: cache-control,content-type,pragma
Access-Control-Max-Age: 3600
Access-Control-Allow-Origin: null
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

由于整个想法在 Python 中有效,我希望我也可以“模仿”Javascript/Jquery 中的行为。所以我正在寻找你的评论/提示。

注意:当使用 CORS 插件在 Chrome 上运行时,整个事情都可以在 JS 中运行...

【问题讨论】:

  • 显示您的服务器 CORS 配置 - 看起来有问题(在 Access-Control-Allow-Origin: null 中)
  • 那么它也不应该在我本地的 python 中工作,不是吗?
  • 这取决于...取决于您从 python 请求的来源是什么 - 必须存在差异
  • 为了清楚起见更改了帖子
  • 您显示您的 ajax 响应标头,但显示您的 ajax 请求标头(chrome> 控制台> 网络> 您的请求)

标签: javascript python jquery cors


【解决方案1】:

Python 不检查 CORS,浏览器这样做是为了避免 XSS 等安全问题,

您需要让服务器响应标头“Access-Control-Allow-Origin”,并使用所调用端点的域(“https://myCoolServer.azurewebsites.net”?)

如果您希望服务器允许被调用以供任何域使用:

“访问控制允许来源:*”

(目前是“Access-Control-Allow-Origin: null”)

这是必需的,因为浏览器需要知道该服务器是否希望从该域调用。

【讨论】:

    【解决方案2】:

    CORS 规则主要由客户端执行,而不是由服务器执行。您的 python 脚本没有实现这些规则,因此请求成功,但您的浏览器确实实现了它们并阻止了请求。

    现在服务器应该向客户端提供有关是否允许 CORS 请求的信息。预检请求只是为了获取此信息(因为您的请求不是“简单请求”,参见this doc)。在您的情况下,显然服务器配置不正确:

    Access-Control-Allow-Origin: null
    

    您应该使用“*”而不是 null,或者至少应该使用“https://myCoolServer.azurewebsites.net”。

    【讨论】:

      猜你喜欢
      • 2014-09-03
      • 1970-01-01
      • 2021-03-27
      • 2015-08-10
      • 2013-10-24
      • 2015-11-26
      • 2020-11-18
      • 2014-10-31
      • 2020-10-26
      相关资源
      最近更新 更多