AJAX를 사용하여 도메인 간 엔드 포인트로드


131

AJAX를 사용하여 크로스 도메인 HTML 페이지를로드하려고하는데 dataType이 "jsonp"가 아니면 응답을 얻을 수 없습니다. 그러나 jsonp를 사용하면 브라우저에서 스크립트 MIME 유형이 필요하지만 "text / html"이 수신됩니다.

요청에 대한 코드는 다음과 같습니다.

$.ajax({
    type: "GET",
    url: "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P@ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute",
    dataType: "jsonp",
}).success( function( data ) {
    $( 'div.ajax-field' ).html( data );
});

요청에 jsonp를 사용하지 않는 방법이 있습니까? 이미 crossDomain 매개 변수를 사용해 보았지만 작동하지 않았습니다.

jsonp에서 html 컨텐츠를 수신하는 방법이 없다면? 현재 콘솔은 jsonp 응답에서 "예기치 않은 <"이라고 말합니다.


여기에 설명 된대로 나는 proxy.php을 만들어 문제를 해결 한 scode7.blogspot.com/2019/11/...
CodeDezk

답변:


235

jQuery 아약스 노트

  • 브라우저 보안 제한으로 인해 대부분의 Ajax 요청에는 동일한 오리진 정책 이 적용됩니다 . 요청이 다른 도메인, 하위 도메인, 포트 또는 프로토콜에서 데이터를 성공적으로 검색 할 수 없습니다.
  • 스크립트 및 JSONP 요청에는 동일한 원본 정책 제한이 적용되지 않습니다.

도메인 간 장벽 을 극복하는 몇 가지 방법이 있습니다 .

도메인 간 요청에 도움이되는 플러그인이 있습니다 .

헤즈 업!

이 문제를 극복하는 가장 좋은 방법은 백엔드에 동일한 원본 정책 제한 이 없으므로 프록시가 다른 도메인의 서비스를 가리 키도록 백엔드에 자신의 프록시를 만드는 것 입니다. 그러나 백엔드에서이를 수행 할 수없는 경우 다음 팁에주의하십시오.


경고!

그들이 공공 정보를 사용할 수 있도록 사용자의 데이터를 추적,하지만 할 수 있기 때문에 타사 프록시를 사용하는 것은 안전한 방법이 아닙니다 결코 개인 데이터.


아래에 표시된 코드 예제는 jQuery.get ()jQuery.getJSON ()을 사용 하며 둘 다 jQuery.ajax () 의 속기 방법입니다.


어느 곳에서나 CORS

CORS Anywhere는 프록시 요청에 CORS 헤더를 추가 하는 node.js 프록시 입니다.
API를 사용하려면 URL 앞에 API URL을 붙이십시오. ( https 지원 : github 저장소 참조 )

필요한 경우 도메인 간 요청을 자동으로 사용하려면 다음 스 니펫을 사용하십시오.

$.ajaxPrefilter( function (options) {
  if (options.crossDomain && jQuery.support.cors) {
    var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
    options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
    //options.url = "http://cors.corsproxy.io/url=" + options.url;
  }
});

$.get(
    'http://en.wikipedia.org/wiki/Cross-origin_resource_sharing',
    function (response) {
        console.log("> ", response);
        $("#viewer").html(response);
});


어떤 기원

Origin무엇이든간에 도메인 간 jsonp 액세스입니다. 이것은 anyorigin.com 의 오픈 소스 대안입니다 입니다.

google.com 에서 데이터를 가져 오려면 다음 스 니펫을 사용할 수 있습니다.

// It is good specify the charset you expect.
// You can use the charset you want instead of utf-8.
// See details for scriptCharset and contentType options: 
// http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
$.ajaxSetup({
    scriptCharset: "utf-8", //or "ISO-8859-1"
    contentType: "application/json; charset=utf-8"
});

$.getJSON('http://whateverorigin.org/get?url=' + 
    encodeURIComponent('http://google.com') + '&callback=?',
    function (data) {
        console.log("> ", data);

        //If the expected response is text/plain
        $("#viewer").html(data.contents);

        //If the expected response is JSON
        //var response = $.parseJSON(data.contents);
});


CORS 프록시

CORS 프록시는 모든 웹 사이트에 대해 CORS 요청을 활성화 하는 간단한 node.js 프록시 입니다. 사이트의 자바 스크립트 코드가 동일한 출처 정책으로 인해 일반적으로 차단되는 다른 도메인의 리소스에 액세스 할 수 있습니다.

어떻게 작동합니까? CORS Proxy는 HTML 5와 함께 추가 된 기능인 Cross-Origin Resource Sharing을 활용합니다. 서버는 다른 웹 사이트가 호스팅하는 리소스를 브라우저가 허용하도록 브라우저를 지정할 수 있습니다. CORS 프록시는 단순히 "누구든지 이것을 요청할 수 있습니다"라는 응답에 헤더를 추가하는 HTTP 프록시입니다.

이것이 목표를 달성하는 또 다른 방법입니다 ( www.corsproxy.com 참조 ). http : //www를 제거하기 만하면됩니다. 프록시 된 URL에서www.corsproxy.com/

$.get(
    'http://www.corsproxy.com/' +
    'en.wikipedia.org/wiki/Cross-origin_resource_sharing',
    function (response) {
        console.log("> ", response);
        $("#viewer").html(response);
});


CORS 프록시 브라우저

최근 에이 것을 발견했으며 다양한 보안 지향의 Cross Origin Remote Sharing 유틸리티가 포함되어 있습니다. 그러나 Flash를 백엔드로 사용하는 블랙 박스입니다.

현재 작업에서 볼 수 있습니다 CORS 프록시 브라우저가
GitHub의에 소스 코드를 가져 오기 : 고토 / 고르 프록시 브라우저



1
이미지, CSS 및 외부 자바 스크립트는 응답 당신이 HTML 문자열을 통해 갈 수 있고, 외부 자원의 SRC 교체, 따라서 다른 기원에서 참조 할 수 있습니다
jherax

1
안녕하세요 jherax html 페이지를 얻기 위해 whateverorigin을 사용했지만 (yql, google 등을 사용하는 방법 만) 영어가 아닌 문자는 이상합니다. data.contents 인코딩 시도했지만 도움이되지 않음
user217648

1
안녕하세요 @Miru는 제목에 "jQuery AJAX를 사용하여 크로스 도메인 html 페이지로드 중"이라고 말하면서 프록시를 사용하여 크로스 도메인 요청을 수행하는 몇 가지 예를 제공하여 제목에 대답했습니다. 또한 질문의 표현에 따라 YQL과 함께 JSONP를 사용하여 도메인 간 요청을 할 수있는 링크를 제공했습니다. 나는 당신이 링크를 읽을 것을 초대합니다, 그들은 매우 유용합니다.
jherax

1
와 CORS Anywhere 방법을 사용하여 끝내고 $.ajaxPrefilter훌륭하게 작동했습니다. 많은 감사합니다!
Joshua Pinter

24

jQuery 플러그인에서 Ajax-cross-origin을 사용할 수 있습니다. 이 플러그인에서는 jQuery.ajax()교차 도메인 을 사용 합니다. 이를 위해 Google 서비스를 사용합니다.

AJAX Cross Origin 플러그인은 Google Apps Script를 jSONP가 구현되지 않은 프록시 jSON getter로 사용합니다. crossOrigin 옵션을 true로 설정하면 플러그인이 원래 URL을 Google Apps Script 주소로 바꾸고 인코딩 된 URL 매개 변수로 보냅니다. Google Apps 스크립트는 Google 서버 리소스를 사용하여 원격 데이터를 가져와 JSONP로 클라이언트에 다시 반환합니다.

사용하는 것은 매우 간단합니다 :

    $.ajax({
        crossOrigin: true,
        url: url,
        success: function(data) {
            console.log(data);
        }
    });

자세한 내용은 여기를 참조하십시오 : http://www.ajax-cross-origin.com/


22
내가 아는 한이 플러그인은 결코 작동하지 않았습니다. Chrome에서는 아무것도하지 않습니다.
Michael

서버를 어떻게 인증 할 수 있습니까?
sttaq

잘 작동합니다! 내가 사용하는 API는 JSONP 또는 CORS를 모두 지원하지 않으므로 이것이 유일하게 작동합니다. 고마워요!
JP Lew

jQuery의 crossOrigin옵션은 확실히 동일한 출처 정책을 완화하기 위해 아무런 작업도 수행하지 않습니다. 가능하다면이 답변을 삭제하겠습니다.
Phil

13

외부 사이트가 JSONP 또는 CORS를 지원하지 않는 경우 유일한 옵션은 프록시를 사용하는 것입니다.

해당 컨텐츠를 요청하는 스크립트를 서버에서 빌드 한 다음 jQuery ajax를 사용하여 서버에서 스크립트를 실행하십시오.


5

PHP 페이지의 헤더에 이것을 넣으면 API 없이는 작동하지 않습니다.

header('Access-Control-Allow-Origin: *'); //allow everybody  

또는

header('Access-Control-Allow-Origin: http://codesheet.org'); //allow just one domain 

또는

$http_origin = $_SERVER['HTTP_ORIGIN'];  //allow multiple domains

$allowed_domains = array(
  'http://codesheet.org',
  'http://stackoverflow.com'
);

if (in_array($http_origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_origin");
}

어디에서 왔는지 궁금 $_SERVER['HTTP_ORIGIN']합니다. PHP 문서 나 다른 곳에서는 찾을 수 없습니다.
Zsolti

흠, 그것은 AJAX 요청으로 채워진 것 같습니다. 어쨌든, 답변 주셔서 감사합니다.
Zsolti

0

누군가 내가 지금 직면하고있는 것과 같은 문제에 직면하는 경우에 이것을 게시하고 있습니다. ZebraNet 프린트 서버가 장착 된 Zebra 감열 식 프린터를 가지고 있는데, 여러 설정을 편집하고 프린터의 현재 상태를 볼 수있는 HTML 기반 사용자 인터페이스를 제공합니다. 프린터의 상태를 가져와야합니다. ZebraNet 서버가 제공하는 html 페이지 중 하나에서, 예를 들어 브라우저에서 사용자에게 메시지를 alert ()합니다. 즉, 해당 HTML 페이지를 Javascript로 먼저 가져와야합니다. 프린터가 사용자 PC의 LAN 내에 있지만 동일한 출처 정책여전히 내 방식대로 단단히 유지되고 있습니다. JSONP를 시도했지만 서버가 html을 반환하고 기능을 수정하는 방법을 찾지 못했습니다 (가능한 경우 이미 매직 헤더 Access-control-allow-origin : *을 설정했을 것입니다). 그래서 C #으로 작은 콘솔 앱을 작성하기로 결정했습니다. 제대로 작동하려면 관리자 권한으로 실행해야합니다. 그렇지 않으면 예외가 발생합니다. 다음은 몇 가지 코드입니다.

// Create a listener.
        HttpListener listener = new HttpListener();
        // Add the prefixes.
        //foreach (string s in prefixes)
        //{
        //    listener.Prefixes.Add(s);
        //}
        listener.Prefixes.Add("http://*:1234/"); // accept connections from everywhere,
        //because the printer is accessible only within the LAN (no portforwarding)
        listener.Start();
        Console.WriteLine("Listening...");
        // Note: The GetContext method blocks while waiting for a request. 
        HttpListenerContext context;
        string urlForRequest = "";

        HttpWebRequest requestForPage = null;
        HttpWebResponse responseForPage = null;
        string responseForPageAsString = "";

        while (true)
        {
            context = listener.GetContext();
            HttpListenerRequest request = context.Request;
            urlForRequest = request.RawUrl.Substring(1, request.RawUrl.Length - 1); // remove the slash, which separates the portNumber from the arg sent
            Console.WriteLine(urlForRequest);

            //Request for the html page:
            requestForPage = (HttpWebRequest)WebRequest.Create(urlForRequest);
            responseForPage = (HttpWebResponse)requestForPage.GetResponse();
            responseForPageAsString = new StreamReader(responseForPage.GetResponseStream()).ReadToEnd();

            // Obtain a response object.
            HttpListenerResponse response = context.Response;
            // Send back the response.
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseForPageAsString);
            // Get a response stream and write the response to it.
            response.ContentLength64 = buffer.Length;
            response.AddHeader("Access-Control-Allow-Origin", "*"); // the magic header in action ;-D
            System.IO.Stream output = response.OutputStream;
            output.Write(buffer, 0, buffer.Length);
            // You must close the output stream.
            output.Close();
            //listener.Stop();

콘솔 사용자를 관리자 권한으로 실행하기 만하면됩니다. 나는 그것이 너무 실망스럽고 복잡하다는 것을 알고 있지만 어떤 식 으로든 서버를 수정할 수없는 경우 도메인 정책 문제에 대한 해결 방법입니다.

편집 : js에서 간단한 아약스 호출을합니다.

$.ajax({
                type: 'POST',
                url: 'http://LAN_IP:1234/http://google.com',
                success: function (data) {
                    console.log("Success: " + data);
                },
                error: function (e) {
                    alert("Error: " + e);
                    console.log("Error: " + e);
                }
            });

요청 된 페이지의 html이 반환되어 data 변수에 저장됩니다 .


0

jherax가 제안한 로컬 프록시를 사용하여 데이터 양식 외부 사이트를 얻으려면 각 외부 URL에서 콘텐츠를 가져오고 해당 PHP 페이지에 get 요청을 보내는 php 페이지를 만들 수 있습니다.

var req = new XMLHttpRequest();
req.open('GET', 'http://localhost/get_url_content.php',false);
if(req.status == 200) {
   alert(req.responseText);
}

PHP 프록시로 https://github.com/cowboy/php-simple-proxy 를 사용할 수 있습니다


0

귀하는 URL요즘 작동하지 않습니다,하지만 당신의 코드는이 작업 솔루션을 업데이트 할 수 있습니다 :

var url = "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P@ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute";

url = 'https://google.com'; // TEST URL

$.get("https://images"+~~(Math.random()*33)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=" + encodeURI(url), function(data) {
    $('div.ajax-field').html(data);
});
<div class="ajax-field"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


-2

적절한 CORS 헤더 를 사용하여 브라우저에서 요청한 서비스로 요청을 프록시하는 CORS 프록시가 필요합니다 . 이러한 서비스 목록은 아래 코드 스 니펫에 있습니다. 제공된 코드 스 니펫을 실행하여 해당 위치에서 해당 서비스에 대한 핑을 볼 수도 있습니다.

$('li').each(function() {
  var self = this;
  ping($(this).text()).then(function(delta) {
    console.log($(self).text(), delta, ' ms');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/jdfreder/pingjs/c2190a3649759f2bd8569a72ae2b597b2546c871/ping.js"></script>
<ul>
  <li>https://crossorigin.me/</li>
  <li>https://cors-anywhere.herokuapp.com/</li>
  <li>http://cors.io/</li>
  <li>https://cors.5apps.com/?uri=</li>
  <li>http://whateverorigin.org/get?url=</li>
  <li>https://anyorigin.com/get?url=</li>
  <li>http://corsproxy.nodester.com/?src=</li>
  <li>https://jsonp.afeld.me/?url=</li>
  <li>http://benalman.com/code/projects/php-simple-proxy/ba-simple-proxy.php?url=</li>
</ul>


11
이것은 어떤 식 으로든 질문에 대답하지 않습니다.
0xc0de

@ 0xc0de 나는 마침내 답을 썼습니다.
galeksandrp

-7

알아 냈습니다. 대신 이것을 사용했습니다.

$('.div_class').load('http://en.wikipedia.org/wiki/Cross-origin_resource_sharing #toctitle');

거기에 사용한 코드는 관련이 없습니다. 중요한 것은 서버 측 CORS 헤더입니다.
Quentin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.