AJAX 도메인 간 호출
AJAX 도메인 간 정책에 대해 알고 있습니다. 따라서 ajax HTTP 요청을 통해 " http://www.google.com "을 호출 하여 내 사이트 어딘가에 결과를 표시 할 수 없습니다 .
실제로 작동하는 dataType "jsonp"로 시도했지만 구문 오류가 발생합니다 (수신 된 데이터가 JSON 형식이 아니기 때문에)
외부 도메인에서 데이터를 수신 / 표시 할 수있는 다른 가능성이 있습니까? iFrame은 동일한 정책을 따르나요?
AJAX를 사용하여 도메인 간 데이터를 얻는 유일한 (쉬운) 방법은 Andy E가 언급 한 것처럼 서버 측 언어를 프록시로 사용하는 것 입니다. 다음은 jQuery를 사용하여 구현하는 방법에 대한 작은 샘플입니다.
jQuery 부분 :
$.ajax({
url: 'proxy.php',
type: 'POST',
data: {
address: 'http://www.google.com'
},
success: function(response) {
// response now contains full HTML of google.com
}
});
그리고 PHP (proxy.php) :
echo file_get_contents($_POST['address']);
그렇게 간단합니다. 스크랩 된 데이터로 할 수있는 작업과 할 수없는 작업을 알고 있어야합니다.
데이터를 참조하는 페이지에 스크립트 태그를 동적으로 삽입해야합니다. JSONP를 사용하면 스크립트가로드되었을 때 일부 콜백 함수를 실행할 수 있습니다.
JSONP 의 위키 백과 페이지 에는 간결한 예가 있습니다. 스크립트 태그 :
<script type="text/javascript" src="http://domain1.com/getjson?jsonp=parseResponse">
</script>
호출에 래핑 된 JSON 데이터를 반환합니다 parseResponse.
parseResponse({"Name": "Cheeso", "Rank": 7})
( getjsondomain1.com 의 스크립트 구성에 따라 다름 )
태그를 동적으로 삽입하는 코드는 다음과 같습니다.
var s = document.createElement("script");
s.src = "http://domain1.com/getjson?jsonp=parseResponse";
s.type = "text/javascript";
document.appendChild(s);
자체 프록시를 호스팅 할 필요없이 YQL 을 사용 하여 요청을 수행 할 수 있습니다 . 명령을 더 쉽게 실행할 수 있도록 간단한 기능을 만들었습니다.
function RunYQL(command, callback){
callback_name = "__YQL_callback_"+(new Date()).getTime();
window[callback_name] = callback;
a = document.createElement('script');
a.src = "http://query.yahooapis.com/v1/public/yql?q="
+escape(command)+"&format=json&callback="+callback_name;
a.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(a);
}
jQuery가있는 경우 대신 $ .getJSON을 사용할 수 있습니다.
샘플은 다음과 같습니다.
RunYQL('select * from html where url="http://www.google.com/"',
function(data){/* actions */}
);
불행히도 (또는 다행스럽게도) 아닙니다. 교차 도메인 정책은 이유가 있습니다. 쉽게 우회 할 수 있다면 보안 조치로서 그다지 효과적이지 않을 것입니다. JSONP 이외의 유일한 옵션은 자체 서버를 사용하여 페이지 를 프록시하는 것 입니다.
iframe을 사용하면 동일한 정책이 적용됩니다. 물론 외부 도메인의 데이터를 표시 할 수 있지만 조작 할 수는 없습니다.
이 코드를 도메인 간 ajax 호출에 사용합니다. 여기에서 하나 이상의 코드가 도움이되기를 바랍니다. 저는 Prototype 라이브러리를 사용하고 있으며 JQuery 또는 Dojo 또는 다른 것으로 동일한 작업을 수행 할 수 있습니다.
1 단계 : 새 js 파일을 만들고이 클래스를 안에 넣습니다. xss_ajax.js라고했습니다.
var WSAjax = Class.create ({
initialize: function (_url, _callback){
this.url = _url ;
this.callback = _callback ;
this.connect () ;
},
connect: function (){
var script_id = null;
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', this.url);
script.setAttribute('id', 'xss_ajax_script');
script_id = document.getElementById('xss_ajax_script');
if(script_id){
document.getElementsByTagName('head')[0].removeChild(script_id);
}
// Insert <script> into DOM
document.getElementsByTagName('head')[0].appendChild(script);
},
process: function (data){
this.callback(data) ;
}
}) ;
This class creates a dynamic script element which src attributes targets your JSON data provider (JSON-P in fact as your distant server must provide the data in this format :: call_back_function(//json_data_here) :: so when the script tag is created your JSON will be directly evaled as a function (we'll talk about passing the callback method name to server on step 2), the main concept behind this is that script like img elements are not concerned by the SOP constraints.
Step2: in any html page where you wanna pull the JSON asynchronously (we call this AJAJ ~ Asynchronous JAvascript + JSON :-) instead of AJAX which use the XHTTPRequest object) do like below
//load Prototype first
//load the file you've created in step1
var xss_crawler = new WSAjax (
"http://your_json_data_provider_url?callback=xss_crawler.process"
, function (_data){
// your json data is _data and do whatever you like with it
}) ;
D'you remenber the callback on step 1? so we pass it to the server and it will returns the JSON embeded in that method so in our case the server will return an evalable javascript code xss_crawler.process(//the_json_data), remember that xss_crawler is an instance of WSAjax class. The server code depends on you (if it's yours), but most of Ajax data providers let you specify the callback method in parameters like we did. In Ruby on rails I just did
render :json=>MyModel.all(:limit=>10), :callback => params[:callback],:content_type => "application/json"
and that's all, you can now pull data from another domain from your apps (widgets, maps etc), in JSON format only, don't forget.
I hope it was helpfull, thanks for your patience :-), peace and sorry for code formatting, it doesn't work well
after doing some research, the only "solution" to this problem is to call:
if($.browser.mozilla)
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
this will ask an user if he allows a website to continue. After he confirmed that, all ajax calls regardless of it's datatype will get executed.
This works for mozilla browsers, in IE < 8, an user has to allow a cross domain call in a similar way, some version need to get configured within browser options.
chrome/safari: I didn't find a config flag for those browsers so far.
using JSONP as datatype would be nice, but in my case I don't know if a domain I need to access supports data in that format.
Another shot is to use HTML5 postMessage which works cross-domain aswell, but I can't afford to doom my users to HTML5 browsers.
JSONP is the best option, in my opinion. Try to figure out why you get the syntax error - are you sure the received data is not JSON? Then maybe you're using the API wrong somehow.
Another way you could use, but I don't think that it applies in your case, is have an iFrame in the page which src is in the domain you want to call. Have it do the calls for you, and then use JS to communicate between the iFrame and the page. This will bypass the cross domain, but only if you can have the iFrame's src in the domain you want to call.
If you are using a php script to get the answer from the remote server, add this line at the begining:
header("Access-Control-Allow-Origin: *");
Here is an easy way of how you can do it, without having to use anything fancy, or even JSON.
First, create a server side script to handle your requests. Something like http://www.example.com/path/handler.php
You will call it with parameters, like this: .../handler.php?param1=12345¶m2=67890
Inside it, after processing the recieved data, output:
document.serverResponse('..all the data, in any format that suits you..');
// Any code could be used instead, because you dont have to encode this data
// All your output will simply be executed as normal javascript
Now, in the client side script, use the following:
document.serverResponse = function(param){ console.log(param) }
var script = document.createElement('script');
script.src='http://www.example.com/path/handler.php?param1=12345¶m2=67890';
document.head.appendChild(script);
The only limit of this approach, is the max length of parameters that you can send to the server. But, you can always send multiple requests.
You can use the technology CORS to configure both servers (the server where the Javascript is running and the external API server)
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
p.s.: the answer https://stackoverflow.com/a/37384641/6505594 is also suggesting this approach, and it's opening the external API server to everyone else to call it.
I faced the same problem during 2 days and I found the solution, and it's elegant after googling a lot. I needed xss Ajax for some widget clients which pull datastream from tiers websites to my Rails app. here's how I did.
참고URL : https://stackoverflow.com/questions/2558977/ajax-cross-domain-call
'Program Club' 카테고리의 다른 글
| 32 비트 정수를 사용하여 충돌 률이 낮은 고속 문자열 해싱 알고리즘 (0) | 2020.11.17 |
|---|---|
| 클래스 이름을 C #의 문자열로 가져옵니다. (0) | 2020.11.17 |
| Java에서 Comparable.compareTo의 반환 값은 무엇을 의미합니까? (0) | 2020.11.16 |
| 이터 러블을 일정한 크기의 청크로 분할하는 방법 (0) | 2020.11.16 |
| WinRT의 UI 스레드에서 코드 실행 (0) | 2020.11.16 |