jQuery预检请求CORS

时间:2018-11-19 08:30:09

标签: javascript python jquery cors

我正在编写网络地图,并尝试从确实具有其凭据的网络资源中获取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中重新创建此代码,以在Webmap中获取数据:

$.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。但是,由于FF中的控制台和Chrome给了我,所以我还没有完成POST:

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中使用...

2 个答案:

答案 0 :(得分:2)

Python不会检查CORS,而浏览器会避免XSS之类的安全性问题

您需要使服务器使用被称为终结点(“ https://myCoolServer.azurewebsites.net”的域的域来响应标头“ Access-Control-Allow-Origin”

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

“访问控制权限来源:*”

(当前为“ Access-Control-Allow-Origin:null”)

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

答案 1 :(得分:2)

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

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

Access-Control-Allow-Origin: null

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