我正在尝试向https://developers.zomato.com/api/v2.1/search提及Zomato API
的AJAX请求服务器有标题:
"access-control-allow-methods": "GET, POST, DELETE, PUT, PATCH, OPTIONS",
"access-control-allow-origin": "*"
问题是API需要为用户密钥设置额外的标头。但是每当我设置自定义标题时,chrome就会通过向上面的URL发送OPTIONS请求来执行飞行前请求,这个请求失败了,因此AJAX请求也失败了。
如果我没有设置标题,那么我没有收到CORS错误,而是来自服务器的禁止错误,因为我没有设置用户密钥标题。
任何方式来解决这个问题22?
Jquery和JavaScript方式都失败了:
$(document).ready(function () {
$.ajax({
url: 'https://developers.zomato.com/api/v2.1/search',
headers: {
'Accept': 'application/json',
'user_key': 'XXXXX'
},
success: function (data) {
console.log(data);
}
});
});
var xhr = new XMLHttpRequest();
var url = 'https://developers.zomato.com/api/v2.1/search';
xhr.open('GET', url, false);
xhr.setRequestHeader('Accept', 'application/json');
xhr.setRequestHeader('user_key', 'XXXXXX');
xhr.send(null);
if (xhr.status == 200) {
console.log(xhr.responseText);
}
我得到的错误:
OPTIONS https://developers.zomato.com/api/v2.1/search
XMLHttpRequest cannot load https://developers.zomato.com/api/v2.1/search. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 501.
如果有人想要重现,您可以在此处获得免费的用户密钥: https://developers.zomato.com/api
答案 0 :(得分:2)
浏览器似乎没有针对此问题的解决方法。如果需要任何自定义标头,CORS规范要求浏览器使用OPTIONS请求预检请求。并且,当它执行OPTIONS预检时,它不包括您的自定义标头,因为OPTIONS请求的一部分是找出允许在请求上发送的自定义标头。因此,如果服务器希望从浏览器开始工作,则不应该在OPTIONS请求上要求自定义标头。
因此,如果服务器要求自定义标头位于OPTIONS请求上,那么服务器只是期待浏览器不会发生的事情。
请参阅相关答案,详细说明:
jQuery CORS Content-type OPTIONS
Cross Domain AJAX preflighting failing Origin check
How do you send a custom header in a cross-domain (CORS) XMLHttpRequest?
Using CORS for Cross-Domain Ajax Requests
并且,另一位在此处遇到相同问题的用户:
看来Zomato不是浏览器友好的,但需要从没有CORS限制的服务器进行访问。
仅供参考,从Zomato回来的错误是501,这意味着OPTIONS命令没有实现。因此,看起来它不仅仅是使用OPTIONS命令发送密钥,而且Zomato不支持OPTIONS命令,但这是在浏览器的跨源请求中使用自定义标头所必需的。
答案 1 :(得分:2)
您无法绕过Access-Control-Allow-Headers in preflight response
。
然而正如@Jaromanda X在评论中提到的那样,Zomato发送:
Access-Control-Allow-Headers:X-Zomato-API-Key
...意味着您只能从浏览器发送此非标准标头。当jQuery有漂亮的准备好的短片时,也不要在请求定义中过低......
$.ajax({
type: "GET", //it's a GET request API
headers: {
'X-Zomato-API-Key': 'YOUR_API_KEY' //only allowed non-standard header
},
url: 'https://developers.zomato.com/api/v2.1/dailymenu', //what do you want
dataType: 'json', //wanted response data type - let jQuery handle the rest...
data: {
//could be directly in URL, but this is more pretty, clear and easier to edit
res_id: 'YOUR_RESTAURANT_OR_PLACE_ID',
},
processData: true, //data is an object => tells jQuery to construct URL params from it
success: function(data) {
console.log(data); //what to do with response data on success
}
});