jQuery AJAX 크로스 도메인


477

다음은 test.php와 testserver.php의 두 페이지입니다.

test.php

<script src="scripts/jq.js" type="text/javascript"></script>
<script>
    $(function() {
        $.ajax({url:"testserver.php",
            success:function() {
                alert("Success");
            },
            error:function() {
                alert("Error");
            },
            dataType:"json",
            type:"get"
        }
    )})
</script>

testserver.php

<?php
$arr = array("element1",
             "element2",
             array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>

이제 내 문제 :이 두 파일이 같은 서버 (localhost 또는 웹 서버)에 있으면 작동하고 alert("Success")호출됩니다. 웹 서버의 testserver.php와 localhost의 test.php를 의미하는 다른 서버에 있으면 작동하지 않고 alert("Error")실행 중입니다. ajax 내부의 URL이 http://domain.com/path/to/file/testserver.php 로 변경된 경우에도


38
들르는 사람들을 위해. 크로스 도메인 자바 스크립트 작업 호출하는 방법을 생각하려면이 읽기 stackoverflow.com/a/11736771/228656을
압둘 Munim

1
이 질문에 대한 답을 여기에 작성했습니다. jQuery AJAX를 사용하여 크로스 도메인 HTML 페이지로드마지막, https 지원
jherax

답변:


412

JSONP를 사용하십시오 .

jQuery :

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
});

PHP :

<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>

에코가 잘못되었을 수 있습니다. PHP를 사용한 지 오래되었습니다. 어쨌든 callbackName('jsonString')따옴표 를 출력해야 합니다. jQuery는 자체 콜백 이름을 전달하므로 GET 매개 변수에서 가져와야합니다.

Stefan Kendall이 게시 한 것처럼 $ .getJSON () 은 속기 방법이지만 'callback=?'URL에 GET 매개 변수로 추가해야합니다 (예, 값은?, jQuery는 이것을 자체 생성 된 콜백 메소드로 바꿉니다).


2
callbackName('/* json */')대신에 귀국해야 callbackName(/* json */)합니까?
Eric

3
@eric 콜백에는 JSON 문자열이 필요합니다. 이론적으로 객체도 작동하지만 jQuery가 어떻게 응답하는지 확실하지 않으면 오류가 발생하거나 자동으로 실패 할 수 있습니다.
BGerrissen

다음과 같은 오류가 발생합니다. SyntaxError : 누락; 명령문 { "ResultCode": 2} 이전. 여기서 { "ResultCode": 2}는 응답입니다. 조언을 부탁드립니다.
user2003356

@ user2003356은 JSONP 대신 일반 JSON을 반환하는 것처럼 보입니다. callbackFunction ({ "ResultCode": 2})와 같은 것을 반환해야합니다. jQuery는 GET 매개 변수 'callback'을 요청에 추가합니다. 이는 jquery가 사용하는 콜백 함수의 이름이며 응답에 추가되어야합니다.
BGerrissen

2
CORS는 이제 해킹으로 만 설명 할 수있는 JSONP와 달리 널리 지원되는 표준입니다. 아래의 @joshuarh의 답변이 지금 선호되는 답변이어야합니다.
Vicky Chijwani

202

JSONP는 좋은 옵션이지만 더 쉬운 방법이 있습니다. Access-Control-Allow-Origin서버에서 간단히 헤더를 설정할 수 있습니다 . *모든 도메인의 도메인 간 AJAX 요청을 수락 하도록 설정 합니다. ( https://developer.mozilla.org/en/http_access_control )

이를 수행하는 방법은 물론 언어마다 다릅니다. 여기 레일스에 있습니다.

class HelloController < ApplicationController
  def say_hello
    headers['Access-Control-Allow-Origin'] = "*"
    render text: "hello!"
  end
end

이 예에서 say_hello작업은 모든 도메인의 AJAX 요청을 수락하고 "hello!"응답을 반환합니다.

다음은 반환 할 수있는 헤더의 예입니다.

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive

그대로, 일부 브라우저 제한이 있습니다. http://caniuse.com/#feat=cors를 참조 하십시오 .


12
Jsonp는 게시, 넣기 및 삭제를 지원하지 않았습니다. 귀하의 솔루션은 훌륭하게 작동합니다.
TonyTakeshi

35
PHP 헤더에서 ( "Access-Control-Allow-Origin : *");
SparK September

9
@Warrior jQuery의 .post()방법을 사용하는 경우 jQuery에서 도메인 간 지원을 활성화해야합니다. 이 작업은 다음과 같습니다 $.support.cors = true..
Friederike

21
이 방법으로 서버를 구성 할 때의 보안 영향은 무엇입니까?
Jon Schneider

19
wilcard "*"를 사용하는 대신 데이터를 공유하려는 도메인 만 허용하는 것이 좋습니다.
Sebastián Grignoli

32

Access-Control-Allow-Origin 을 추가하여 HTTP 헤더를 통해이를 제어 할 수 있습니다 . *로 설정하면 모든 도메인의 도메인 간 AJAX 요청을 수락합니다.

PHP를 사용하면 정말 간단합니다. 도메인 외부에서 액세스하려는 스크립트에 다음 줄을 추가하십시오.

header("Access-Control-Allow-Origin: *");

httpd.conf에서 mod_headers 모듈을 활성화하는 것을 잊지 마십시오.


당신은 내 하루를 구했다.
NomanJaved

20

동일 출처 정책을 살펴 봐야합니다 .

컴퓨팅에서 동일한 출처 정책은 JavaScript와 같은 여러 브라우저 측 프로그래밍 언어에 대한 중요한 보안 개념입니다. 이 정책은 동일한 사이트에서 시작된 페이지에서 실행되는 스크립트가 특별한 제한없이 서로의 메서드 및 속성에 액세스 할 수 있도록하지만 다른 사이트의 페이지에서 대부분의 메서드 및 속성에 액세스 할 수는 없습니다.

데이터를 얻을 수 있으려면 다음과 같아야합니다.

동일한 프로토콜 및 호스트

해결 하려면 JSONP 를 구현해야 합니다.


17

로컬 디스크 "file : /// C : /test/htmlpage.html"에서 웹 페이지를로드하고 "http : //localhost/getxml.php"url을 호출하여 IE8 + 및 Firefox12 + 브라우저에서 jQuery v1을 사용하여 웹 페이지를로드해야했습니다. .7.2 상용구 코드를 최소화하는 lib. 수십 개의 기사를 읽은 후 마침내 알아 냈습니다. 여기 내 요약이 있습니다.

  • 서버 스크립트 (.php, .jsp, ...)는 http 응답 헤더 Access-Control-Allow-Origin을 반환해야합니다. *
  • jQuery 아약스를 사용하기 전에 자바 스크립트에서이 플래그를 설정하십시오. jQuery.support.cors = true;
  • jQuery ajax 함수를 사용하기 전에 한 번 또는 매번 플래그를 설정할 수 있습니다
  • 이제 IE와 Firefox에서 .xml 문서를 읽을 수 있습니다. 내가 테스트하지 않은 다른 브라우저.
  • 응답 문서는 일반 / 텍스트, xml, json 또는 기타 모든 것이 될 수 있습니다.

다음은 디버그 sysout이 포함 된 jQuery ajax 호출 예제입니다.

jQuery.support.cors = true;
$.ajax({
    url: "http://localhost/getxml.php",
    data: { "id":"doc1", "rows":"100" },
    type: "GET",
    timeout: 30000,
    dataType: "text", // "xml", "json"
    success: function(data) {
        // show text reply as-is (debug)
        alert(data);

        // show xml field values (debug)
        //alert( $(data).find("title").text() );

        // loop JSON array (debug)
        //var str="";
        //$.each(data.items, function(i,item) {
        //  str += item.title + "\n";
        //});
        //alert(str);
    },
    error: function(jqXHR, textStatus, ex) {
        alert(textStatus + "," + ex + "," + jqXHR.responseText);
    }
});

1
이 질문에 대한 답변을 여기에 작성했습니다. jQuery AJAX를 사용하여 크로스 도메인 html 페이지로드마지막 하나는 https를 지원합니다
jherax

가장 중요한 점 : PHP에서 다음 줄을 스크립트에 추가하십시오.header("Access-Control-Allow-Origin: *");
T30

1
@ whome 당신의 답변에 대단히 감사합니다. 당신은 저를 많이 도와주었습니다. 건배.
Luis Milanese

10

동일한 출처 정책으로 인해 JavaScript가 여러 도메인에서 요청하는 것을 막을 수는 있지만 CORS 사양은 원하는 API 액세스 유형 만 허용하며 현재 주요 브라우저 모음에서 지원됩니다.

클라이언트 및 서버에 대해 출처 간 자원 공유를 사용하는 방법을 참조하십시오.

http://enable-cors.org/

"CORS (Cross-Origin Resource Sharing)는 도메인 경계를 넘어 진정한 개방형 액세스를 가능하게하는 사양입니다. 공용 컨텐츠를 제공하는 경우 CORS를 사용하여 범용 JavaScript / 브라우저 액세스를 위해 열어보십시오."



9

Apache 서버를 사용하므로 mod_proxy 모듈을 사용했습니다. 모듈 활성화 :

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

그런 다음 다음을 추가하십시오.

ProxyPass /your-proxy-url/ http://service-url:serviceport/

마지막으로 proxy-url을 스크립트에 전달하십시오.


8

브라우저 보안은 한 도메인에 호스팅 된 페이지에서 다른 도메인에 호스팅 된 페이지로 아약스 호출을 방지합니다. 이것을 " 동일 출처 정책 "이라고합니다.



4

Jquery 문서에서 ( link ) :

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

  • 스크립트 및 JSONP 요청에는 동일한 원본 정책 제한이 적용되지 않습니다.

따라서 요청에 jsonp를 사용해야한다고 생각합니다. 그러나 이것을 직접 시도하지 않았습니다.


2

문제를 해결하는 3 가지 방법을 알고 있습니다.

  1. 먼저 두 도메인에 모두 액세스 할 수있는 경우 다음을 사용하여 다른 모든 도메인에 대한 액세스를 허용 할 수 있습니다.

    header("Access-Control-Allow-Origin: *");

    또는 .htaccess 파일에 코드를 추가하여 도메인 만 :

    <FilesMatch "\.(ttf|otf|eot|woff)$"> <IfModule mod_headers.c> SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0 Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin </IfModule> </FilesMatch>

  2. 서버의 PHP 파일에 ajax 요청을 하고이 PHP 파일을 사용하여 다른 도메인에 대한 요청을 처리 할 수 ​​있습니다.

  3. jsonp는 권한이 필요하지 않기 때문에 사용할 수 있습니다. 이를 위해 당신은 우리의 친구 @BGerrissen 답변을 읽을 수 있습니다.

0

Microsoft Azure의 경우 약간 다릅니다.

Azure에는 설정해야하는 특수 CORS 설정이 있습니다. 본질적으로 뒤에서 똑같지 만 joshuarh가 언급 한 헤더를 설정하면 작동하지 않습니다. 도메인 간 사용을위한 Azure 설명서는 다음에서 찾을 수 있습니다.

https://docs.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript

호스팅 플랫폼 에이 특별한 설정이 있음을 깨닫기 전에 몇 시간 동안이 문제를 해결했습니다.


0

작동합니다. 필요한 모든 것 :

PHP :

header('Access-Control-Allow-Origin: http://www.example.com');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');

JS (jQuery 아약스) :

var getWBody = $.ajax({ cache: false,
        url: URL,
        dataType : 'json',
        type: 'GET',
        xhrFields: { withCredentials: true }
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.