简体   繁体   English

jQuery预检请求CORS

[英]JQuery preflight request CORS

I am writing a web map and try to get fetch a JSON from a web ressource I do have credentials for. 我正在编写网络地图,并尝试从确实具有其凭据的网络资源中获取JSON。 This works great in Python running via a JuPyteR notebook: 这在通过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)

The request from python gives the following 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'

Now I am trying to recreate this in JavaScript to get data in my webmap: 现在,我试图在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;
          }

The console shows the following header for the preflight Options call: 控制台显示预检选项调用的以下标头:

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

The preflight Options response from the server is successfull in terms of a 200 response. 服务器发出的飞行前“选项”响应成功为200。 Yet I don't get the POST finished as the console in FF and Chrome gives me: 但是,由于FF中的控制台和Chrome给我的信息,我并没有完成POST:

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

The response header from the Server gives me: 服务器的响应头给我:

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

As the whole idea works in Python I hope I can "mimicri" the behaviour in Javascript/Jquery as well. 由于整个想法都在Python中起作用,所以我希望我也可以“模仿” Javascript / Jquery中的行为。 So I am looking for your remarks/hints. 因此,我正在寻找您的评论/提示。

Note: The whole thing works in JS when running on Chrome using a CORS plugin... 注意:当使用CORS插件在Chrome上运行时,整件事都可以在JS中使用...

Python does not check CORS and the browser does to avoid security issues like XSS, Python不会检查CORS,而浏览器会避免XSS等安全问题,

You need to make the server respond the header "Access-Control-Allow-Origin" with the domain from what the endpoint is being called (" https://myCoolServer.azurewebsites.net " ?) 您需要使服务器使用被称为端点的域来响应标头“ Access-Control-Allow-Origin”(“ https://myCoolServer.azurewebsites.net ”?)

If you want the server to allow being called for any domain use: 如果希望服务器允许任何域使用被调用:

"Access-Control-Allow-Origin: *" “访问控制允许来源:*”

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

This is needed because the browser needs to know if that server expect to be called from that domain. 这是必需的,因为浏览器需要知道是否希望从该域调用该服务器。

CORS rules are primarily enforced by the client, not by the server. CORS规则主要由客户端而非服务器强制执行。 You python script does not implement these rules, hence the request succeeds, but your browser does implement them and blocks the request. 您Python脚本不执行这些规则,因此请求成功,但你的浏览器落实,并阻止该请求。

Now the server is supposed to provide information to the client about whether to allow the CORS request. 现在,服务器应该向客户端提供有关是否允许CORS请求的信息。 The preflight request is just there to obtain this information (since your request is not a "simple request", cf this doc ). 预检请求就在那里获取此信息(因为您的请求不是“简单请求”,请参见此文档 )。 In your case, clearly the server is not well configured: 在您的情况下,显然服务器配置不正确:

Access-Control-Allow-Origin: null

You should have "*" instead of null, or at least " https://myCoolServer.azurewebsites.net ". 您应该使用“ *”而不是null,或者至少使用“ https://myCoolServer.azurewebsites.net ”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM