获取错误请求错误400尝试将XMLHttpRequest发送到http://api.lbs.yandex.net/geolocation

时间:2017-08-24 01:33:19

标签: geolocation xmlhttprequest cors yandex

我需要将XMLHttpRequest发送到Yandex服务器

我收到错误请求错误(400)和:

  

XMLHttpRequest无法加载http://api.lbs.yandex.net/geolocation。没有   '访问控制允许来源'标题出现在请求的上   资源。起源' http://localhost'因此不允许访问。   响应的HTTP状态代码为400。

这是我的代码:

var xhr = new XMLHttpRequest();
var url = "http://api.lbs.yandex.net/geolocation";

xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

xhr.onreadystatechange = function () {
  <some code>
};

var data = JSON.stringify({
 "common": {
   "version": "1.0",
   "api_key": <here goes API key>
   },
   "gsm_cells": [
   {
   "countrycode": params[0],
   "operatorid": params[1],
   "cellid": params[3],
   "lac": params[2],
   "age": 0
   }
   ]
});

xhr.send(data);

我找不到这么简单(?)的解决方案!

2 个答案:

答案 0 :(得分:1)

该API需要application/x-www-form-urlencoded - 格式化的数据如下所示:

json={"common":{"version":"1.0","api_key":…}…}

也就是说,它需要一个key=value对,字符串json作为键,一些JSON作为值。

但问题中的代码是发送一些JSON而没有必要的json=。因此,API端点以400响应,告诉您这是一个错误的请求。

因此,您可以通过制作代码来解决问题并获得回复:

var data = 'json=' + JSON.stringify({…});

但是,即使你这样做了,你的浏览器仍然不会让你的前端JavaScript访问服务器返回的响应。相反,浏览器将记录如下错误消息:

  

无法加载https://api.lbs.yandex.net/geolocation:请求的资源上没有“Access-Control-Allow-Origin”标头。因此,不允许原点https://foo.bar访问。

...因为CORS协议要求浏览器禁止前端JavaScript代码访问来自跨源请求的响应,除非响应具有Access-Control-Allow-Origin

但是你可以通过CORS代理提出请求来解决这个问题。完整的例子:

var xhr = new XMLHttpRequest();
var proxyurl = "https://cors-anywhere.herokuapp.com/";
var url = "https://api.lbs.yandex.net/geolocation";

xhr.open("POST", proxyurl + url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

xhr.onreadystatechange = function() {
  console.log(xhr.responseText)
};

var data = 'json=' + JSON.stringify({
  "common": {
    "version": "1.0",
    "api_key": "AAwkGkwBAAAA9muWLAMAKp9XjTBZtmOLeiBQJqHX6YEqNdUAAAAAAAAAAAAoEP1ZsBlcVFA_OpP55MK3Ek1r8A=="
  },
  "gsm_cells": [{
    "countrycode": 250,
    "operatorid": 99,
    "cellid": 42332,
    "lac": 36002,
    "age": 0
  }]
});
xhr.send(data);

但是请注意,如果您通过类似的第三方代理发送请求,代理运营商可能会窥探您的api_key以及您可能发送的任何其他凭据。

因此,最好使用https://github.com/Rob--W/cors-anywhere/

设置自己的代理

至于上面示例中的代理如何工作:将https://cors-anywhere.herokuapp.com/前缀到您的请求URL会导致请求通过该代理进行,然后执行:

  1. 将请求转发给https://api.lbs.yandex.net/geolocation
  2. 收到https://api.lbs.yandex.net/geolocation的回复。
  3. Access-Control-Allow-Origin标题添加到回复中。
  4. 将带有添加标题的响应传递回您的请求前端代码。
  5. 然后,浏览器将允许您的前端代码访问响应,因为具有Access-Control-Allow-Origin响应标头的响应是浏览器看到的。

    另见https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

答案 1 :(得分:1)

建议的咳嗽在常见情况下无法正常工作,但对于gcm细胞可正常工作。这是因为yandex.net/geolocation服务用于根据WiFi网络,gcm cell或ip地址获取用户的位置。

当需要仅使用基于IP的方式时,则需要在Web服务器上配置CORS。