Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 22.02.2018, 20:29
Новичок на форуме
Отправить личное сообщение для Николай Волков Посмотреть профиль Найти все сообщения от Николай Волков
 
Регистрация: 22.02.2018
Сообщений: 4

kladr-api.ru и No 'Access-Control-Allow-Origin'
Хочу получить автодополнение при вводе города при помощи http://kladr-api.ru

Прям из учебника код взял для CORS
let XHR = ("onload" in new XMLHttpRequest()) ? XMLHttpRequest : XDomainRequest;

let xhr = new XHR();

xhr.open('GET', 'http://kladr-api.ru/api.php?query=Арх&contentType=city&withParent=1&limit=3', true);

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

xhr.onerror = function() {
    console.log( 'Ошибка ' + this.status );
}

xhr.send();


Ругается: "No 'Access-Control-Allow-Origin' header is present on the requested resource."

Не пойму, что ему не так. На сервисе не нашёл, чтобы нужно было свой домен где-то указывать.

И нагуглить ничего не вышло.
Как его забороть? Или, может, другой сервис использовать?
Ответить с цитированием
  #2 (permalink)  
Старый 22.02.2018, 20:54
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,705

Ниже функция, с помощью которой вы можете работать с клиента (из браузера) с API сервиса kladr-api.ru
Принимает она 1 аргумент - или строку, или объект параметров; возвращает экземпляр промиса (Promise).
Про промисы можно почитать тут: https://learn.javascript.ru/promise.
function request(params){
	var node=document.createElement('script'),src='//kladr-api.ru/api.php?',
		res,rej,
		result=new Promise(function(resolve,reject){
			res=resolve;
			rej=reject;
		});
	
	node.type='text/javascript';
	node.id=(new Date()).getTime()+Math.random();
	node.onerror=function(){
		node.parentNode.removeChild(node);
		rej();
	};
	node.onload=function(){
		node.parentNode.removeChild(node);
	};
	
	if(typeof params=='string')
		src+=['?','&'].indexOf(params.substr(0,1))>-1?params.substr(1):params;
	else if(typeof params=='object')
		src+=Object.keys(params).map(function(key){
			return key+'='+encodeURIComponent(params[key]);
		}).join('&');
	
	var callback='__jsonp_dynamic_callback_'+node.id.toString().replace('.','');
	window[callback]=function(json){
		res(json);
		
		delete window[callback];
	};
	
	node.src=src+(!params?'':'&')+'callback='+callback;
	document.body.appendChild(node);
	
	return result;
};

request('?query=Арх&contentType=city&withParent=1&limit=3').then(function(json){
    console.log(json);
});

Upd. Еще так можно использовать:
request({
    query:'Арх',
    contentType:'city',
    withParent:1,
    limit:3
}).then(function(json){
    console.log(json);
});

Последний раз редактировалось Nexus, 22.02.2018 в 21:03.
Ответить с цитированием
  #3 (permalink)  
Старый 23.02.2018, 16:45
Новичок на форуме
Отправить личное сообщение для Николай Волков Посмотреть профиль Найти все сообщения от Николай Волков
 
Регистрация: 22.02.2018
Сообщений: 4

Спасибо! :-)

Подскажите, где можно почитать про подобный метод использования стороннего api?
"Зачем так? Почему не работает при использовании XHR?"
Ответить с цитированием
  #4 (permalink)  
Старый 23.02.2018, 17:04
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,480

Николай Волков, почему не работает написано английским по белому: "No 'Access-Control-Allow-Origin' header is present on the requested resource." - "Никакого заголовка 'Контроль доступа, разрешить для источника' нет на запрашиваемом ресурсе."
Другими словами ресурс не указал никаким образом, что с него можно хоть что-то забирать клиентским скриптам с других сайтов. А по умолчанию - нельзя.

Предложенный же вариант называется jsonp, и является просто подключением стороннего скрипта на ваш сайт. Весь вышеприведённый код по сути делает:
<script>
function __jsonp_dynamic_callback_random(json){
    res(json);
    delete window.__jsonp_dynamic_callback_random;
};
</script>
<script src="//kladr-api.ru/api.php?query=Арх&contentType=city&withParent=1&limit=3&callback=__jsonp_dynamic_callback_random"></script>
Где res - ваша функция.
Сервер же на своей стороне просто оборачивает отдаваемый json в вызов функции, имя которой передано в параметре callback, т.е. возвращает:
__jsonp_dynamic_callback_random({
  "result": "ответ"
});


Jsonp использовался задолго до того, как стало возможным междоменное взаимодействие. Плюсы - простота и возможность использовать где угодно. Минусы же - безопасность. Если сайт скомпрометирован, то вам может прилететь не только нужный ответ, но и произвольный кусок кода.
__________________
29375, 35

Последний раз редактировалось Aetae, 23.02.2018 в 17:06.
Ответить с цитированием
  #5 (permalink)  
Старый 23.02.2018, 17:14
Новичок на форуме
Отправить личное сообщение для Николай Волков Посмотреть профиль Найти все сообщения от Николай Волков
 
Регистрация: 22.02.2018
Сообщений: 4

Всё понятно! Спасибо!
Ответить с цитированием
  #6 (permalink)  
Старый 23.02.2018, 17:26
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Николай Волков
Подскажите, где можно почитать про подобный метод использования стороннего api?
https://github.com/garakh/kladrapi-jsclient
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ошибка no access control allow origin header is present jquery ajax origin wanes101 AJAX и COMET 4 11.03.2014 00:53
помогите со скриптом jquery hesrun jQuery 24 22.02.2013 12:59