Этот 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: нет доступа Заголовок -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-адрес вашего запроса приводит к тому, что запрос выполняется через этот прокси-сервер, который затем:
- Перенаправляет запрос на любой https://api.lbs.yandex.net/geolocation.
- Получает ответ от https://api.lbs.yandex.net/geolocation.
- Добавляет в ответ заголовок
Access-Control-Allow-Origin
.
- Передает этот ответ с этим добавленным заголовком обратно в ваш запрашивающий интерфейсный код.
Затем браузер разрешит вашему коду внешнего интерфейса получить доступ к ответу, потому что этот ответ с заголовком ответа Access-Control-Allow-Origin
— это то, что видит браузер.
См. также https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
person
sideshowbarker
schedule
24.08.2017