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.