Programing

JavaScript를 통해 도메인 간 POST 요청을 보내려면 어떻게합니까?

lottogame 2020. 2. 9. 20:26
반응형

JavaScript를 통해 도메인 간 POST 요청을 보내려면 어떻게합니까?


JavaScript를 통해 도메인 간 POST 요청을 보내려면 어떻게합니까?

참고-페이지를 새로 고치면 안되며 나중에 응답을 잡고 구문 분석해야합니다.


업데이트 : 계속하기 전에 모든 사람이 CORS에 대한 html5rocks 튜토리얼읽고 이해해야합니다 . 이해하기 쉽고 매우 명확합니다.

POST중인 서버를 제어하는 ​​경우 서버에서 응답 헤더를 설정하여 "Cross-Origin Resource Sharing 표준"을 활용하십시오. 이 답변은이 스레드의 다른 답변에서 논의되지만 내 의견으로는 명확하지 않습니다.

간단히 말해서 from.com/1.html에서 to.com/postHere.php (예를 들어 PHP를 사용)에서 교차 도메인 POST를 수행하는 방법이 있습니다. 참고 : Access-Control-Allow-OriginNON OPTIONS요청에 대해서만 설정하면됩니다. 이 예에서는 항상 더 작은 코드 스 니펫에 대한 모든 헤더를 설정합니다.

  1. postHere.php 설정에서 다음을 수행하십시오.

    switch ($_SERVER['HTTP_ORIGIN']) {
        case 'http://from.com': case 'https://from.com':
        header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
        header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
        header('Access-Control-Max-Age: 1000');
        header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
        break;
    }
    

    이를 통해 스크립트가 도메인 간 POST, GET 및 OPTIONS를 만들 수 있습니다. 계속 읽으면서 이것은 분명해질 것입니다 ...

  2. JS에서 교차 도메인 POST를 설정하십시오 (jQuery 예).

    $.ajax({
        type: 'POST',
        url: 'https://to.com/postHere.php',
        crossDomain: true,
        data: '{"some":"json"}',
        dataType: 'json',
        success: function(responseData, textStatus, jqXHR) {
            var value = responseData.someKey;
        },
        error: function (responseData, textStatus, errorThrown) {
            alert('POST failed.');
        }
    });
    

2 단계에서 POST를 수행하면 브라우저는 서버에 "OPTIONS"메소드를 보냅니다. 이것은 서버에서 POST하는 동안 서버가 멋진 지 확인하기 위해 브라우저에서 "스 니프"입니다. 요청이 " http://from.com "또는 " https://from.com " 에서 시작된 경우 서버는 "Access-Control-Allow-Origin"으로 응답하여 브라우저에게 POST | GET | ORIGIN에 OK를 알려줍니다 . 서버에 문제가 없으므로 브라우저는 두 번째 요청을합니다 (이번에는 POST). 클라이언트가 전송하는 컨텐츠 유형을 설정하도록하는 것이 좋습니다. 따라서이를 허용해야합니다.

MDN은 전체 흐름이 어떻게 작동하는지 자세히 설명하는 HTTP 액세스 제어 에 대한 훌륭한 글을 작성했습니다 . 문서에 따르면 "사이트 간 XMLHttpRequest를 지원하는 브라우저에서 작동"해야합니다. 그러나 현대 브라우저 만 도메인 간 POST를 허용 한다고 생각하기 때문에 약간 오해의 소지가 있습니다. 나는 이것이 사파리, 크롬, FF 3.6에서만 작동하는지 확인했습니다.

이렇게하면 다음을 명심하십시오.

  1. 서버는 작업 당 2 개의 요청을 처리해야합니다.
  2. 보안 영향에 대해 생각해야합니다. 'Access-Control-Allow-Origin : *'과 같은 작업을 수행하기 전에주의하십시오.
  3. 모바일 브라우저에서는 작동하지 않습니다. 내 경험상 그들은 도메인 간 POST를 전혀 허용하지 않습니다. 나는 안드로이드, 아이 패드, 아이폰을 테스트했다
  4. FF <3.6에는 서버가 400이 아닌 응답 코드를 반환하고 응답 본문 (예 : 유효성 검사 오류)이있는 경우 FF 3.6은 응답 본문을 얻지 못하는 꽤 큰 버그가 있습니다. 좋은 REST 사례를 사용할 수 없기 때문에 이것은 엉덩이에 큰 고통입니다. 여기에 버그를 참조 하십시오 (jQuery에 제출되었지만 내 추측은 FF 버그입니다-FF4에서 수정 된 것으로 보입니다).
  5. OPTION 요청뿐만 아니라 항상 위의 헤더를 반환하십시오. FF는 POST의 응답으로 필요합니다.

원격 서버를 제어하는 경우이 답변에 설명 된대로 CORS를 사용해야합니다 . IE8 이상 및 모든 최신 버전의 FF, GC 및 Safari에서 지원됩니다. 그러나 IE8 및 9에서는 CORS가 요청에 쿠키를 보낼 수 없습니다.

따라서 원격 서버를 제어 하지 않거나 IE7을 지원해야하거나 쿠키가 필요하고 IE8 / 9를 지원해야하는 경우 iframe 기술을 사용하고 싶을 것입니다.

  1. 고유 한 이름으로 iframe을 만듭니다. (iframe은 전체 브라우저에 글로벌 네임 스페이스를 사용하므로 다른 웹 사이트에서 사용하지 않는 이름을 선택하십시오.)
  2. 숨겨진 입력으로 iframe을 대상으로 양식을 구성하십시오.
  3. 양식을 제출하십시오.

샘플 코드는 다음과 같습니다. IE6, IE7, IE8, IE9, FF4, GC11, S5에서 테스트했습니다.

function crossDomainPost() {
  // Add the iframe with a unique name
  var iframe = document.createElement("iframe");
  var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
  document.body.appendChild(iframe);
  iframe.style.display = "none";
  iframe.contentWindow.name = uniqueString;

  // construct a form with hidden inputs, targeting the iframe
  var form = document.createElement("form");
  form.target = uniqueString;
  form.action = "http://INSERT_YOUR_URL_HERE";
  form.method = "POST";

  // repeat for each parameter
  var input = document.createElement("input");
  input.type = "hidden";
  input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
  input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
  form.appendChild(input);

  document.body.appendChild(form);
  form.submit();
}

조심해! iframe이 별도의 도메인에 있기 때문에 POST의 응답을 직접 읽을 수 없습니다. 프레임은 서로 다른 도메인에서 서로 통신 할 수 없습니다. 이것은 동일한 출처 정책 입니다.

원격 서버를 제어하지만 CORS를 사용할 수없는 경우 (예 : IE8 / IE9에 있고 쿠키를 사용해야하기 때문에) 동일한 출처 정책을 해결하는 방법 (예 : window.postMessage및 / 또는) 이전 브라우저에서 도메인 간 크로스 프레임 메시지를 보낼 수있는 여러 라이브러리 중 하나 :

원격 서버를 제어하지 않으면 POST 기간의 응답을 읽을 수 없습니다. 그렇지 않으면 보안 문제가 발생할 수 있습니다.


  1. iFrame을 만들고
  2. 숨겨진 입력으로 양식을 넣습니다.
  3. 양식의 동작을 URL로 설정하고
  4. 문서에 iframe 추가
  5. 양식을 제출하십시오

의사 코드

 var ifr = document.createElement('iframe');
 var frm = document.createElement('form');
 frm.setAttribute("action", "yoururl");
 frm.setAttribute("method", "post");

 // create hidden inputs, add them
 // not shown, but similar (create, setAttribute, appendChild)

 ifr.appendChild(frm);
 document.body.appendChild(ifr);
 frm.submit();

숨겨져 있고 절대적으로 배치되도록 iframe 스타일을 지정하고 싶을 것입니다. 브라우저에서 교차 사이트 게시가 허용되는지는 확실하지 않지만 그렇게하는 경우이를 수행하는 방법입니다.


간단하게 유지하십시오.

  1. 도메인 간 POST :
    사용crossDomain: true,

  2. 페이지를 새로 고치면 안됩니다.
    아니요,서버가 응답을 다시 보낼 때success또는error비동기 콜백이 호출되므로페이지를 새로 고치지 않습니다.


스크립트 예 :

$.ajax({
        type: "POST",
        url: "http://www.yoururl.com/",
        crossDomain: true,
        data: 'param1=value1&param2=value2',
        success: function (data) {
            // do something with server response data
        },
        error: function (err) {
            // handle your error logic here
        }
    });

관련된 모든 서버에 액세스 할 수 있으면 다른 도메인에서 요청중인 페이지의 회신 헤더에 다음을 입력하십시오.

PHP :

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

예를 들어 Drupal의 xmlrpc.php 코드에서 다음을 수행합니다.

function xmlrpc_server_output($xml) {
    $xml = '<?xml version="1.0"?>'."\n". $xml;
    header('Connection: close');
    header('Content-Length: '. strlen($xml));
    header('Access-Control-Allow-Origin: *');
    header('Content-Type: application/x-www-form-urlencoded');
    header('Date: '. date('r'));
    // $xml = str_replace("\n", " ", $xml); 

    echo $xml;
    exit;
}

보안 문제가 발생할 수 있으므로 요청을 확인하기 위해 적절한 조치를 취해야합니다.


위에서 설명한 iframe 방법에 대한 좋은 예인 http://taiyolab.com/mbtweet/scripts/twitterapi_call.jspost_method기능을 확인하십시오 .


  1. 두 개의 숨겨진 iframe을 만듭니다 (css 스타일에 "display : none;"추가). 두 번째 iframe이 자신의 도메인에있는 무언가를 가리 키도록합니다.

  2. 숨겨진 양식을 만들고 target = 첫 번째 iframe으로 메소드를 "post"로 설정하고 선택적으로 enctype을 "multipart / form-data"로 설정합니다 (그림과 같은 여러 부분으로 데이터를 보내려고하므로 POST를 수행하려고합니다. ?)

  3. 준비되면, submit () 양식을 POST로 만드십시오.

  4. 다른 도메인에서 Iframe과의 도메인 간 통신 ( http://softwareas.com/cross-domain-communication-with-iframes )을 수행하는 자바 스크립트를 반환하도록하면 운이 좋으며 응답을 캡처 할 수 있습니다 게다가.

물론 서버를 프록시로 사용하려면이 모든 것을 피할 수 있습니다. 다른 서버가 IP 불일치를 통지하도록 설정되어 있지 않다고 가정하면 요청을 다른 서버로 프록시 처리하여 응답을 받고 원하는 것을 반환합니다.


한 가지 더 중요한 점 !!! 위의 에서는 사용 방법을 설명했습니다.

$.ajax({
    type     : 'POST',
    dataType : 'json', 
    url      : 'another-remote-server',
    ...
});

JQuery 1.6 이하에는 도메인 간 XHR에 버그가 있습니다. Firebug에 따르면 OPTIONS 이외의 요청은 전송되지 않았습니다. POST가 없습니다. 조금도.

5 시간 동안 코드를 테스트 / 튜닝했습니다. 원격 서버 (스크립트)에 많은 헤더 추가 효과가 없습니다. 그러나 나중에 JQuery lib를 1.6.4로 업데이트했으며 모든 것이 매력처럼 작동합니다.


JQuery AJAX를 사용하여 ASP.net MVC 환경에서이 작업을 수행하려면 다음 단계를 수행하십시오 ( 스레드 에서 제공되는 솔루션의 요약입니다 ).

"caller.com"(모든 웹 사이트 일 수 있음)이 "server.com"(ASP.net MVC 응용 프로그램)에 게시되어야한다고 가정합니다.

  1. "server.com"앱의 Web.config에서 다음 섹션을 추가하십시오.

      <httpProtocol>
          <customHeaders>
              <add name="Access-Control-Allow-Origin" value="*" />
              <add name="Access-Control-Allow-Headers" value="Content-Type" />
              <add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />
          </customHeaders>
      </httpProtocol>
    
  2. "server.com"에서 우리는 게시 할 컨트롤러 ( "Home")에 대해 다음과 같은 작업을 수행합니다.

    [HttpPost]
    public JsonResult Save()
    {
        //Handle the post data...
    
        return Json(
            new
            {
                IsSuccess = true
            });
    }
    
  3. 그런 다음 "caller.com"에서 다음과 같이 양식 (html ID가 "formId"인)에서 "server.com"으로 데이터를 게시하십시오.

    $.ajax({
            type: "POST",
            url: "http://www.server.com/home/save",
            dataType: 'json',
            crossDomain: true,
            data: $(formId).serialize(),
            success: function (jsonResult) {
               //do what ever with the reply
            },
            error: function (jqXHR, textStatus) {
                //handle error
            }
        });
    

high-level .... other-serve.your-server.com이 other-server.com을 가리 키도록 서버에 cname 설정이 있어야합니다.

페이지가 보이지 않는 iframe을 동적으로 생성하여 other-server.com으로의 전송 역할을합니다. 그런 다음 JS를 통해 페이지에서 other-server.com으로 통신하고 데이터를 다시 페이지로 리턴하는 콜백을 가져와야합니다.

가능하지만 your-server.com 및 other-server.com의 조정이 필요합니다


교차 원본 리소스 공유 폴리 필 중 하나와 함께 XMLHttpRequest (예 : jQuery의 $ .ajax (), $ .post ())를 사용하는 것이 가장 좋은 방법이라고 생각합니다 https://github.com/Modernizr/Modernizr/wiki/HTML5- 크로스 브라우저 폴리 필 # wiki-CORS


html5 기능을 사용하는 또 다른 방법이 있습니다. 다른 도메인에서 호스팅되는 프록시 iframe을 사용하고 postMessage를 사용하여 해당 iframe에 메시지를 보낸 다음 iframe은 POST 요청 (동일한 도메인에서)을 수행하고 postMessage를 상위 창에 다시 배치하여 다시 게시 할 수 있습니다.

sender.com의 부모

var win = $('iframe')[0].contentWindow

function get(event) {
    if (event.origin === "http://reciver.com") {
        // event.data is response from POST
    }
}

if (window.addEventListener){
    addEventListener("message", get, false)
} else {
    attachEvent("onmessage", get)
}
win.postMessage(JSON.stringify({url: "URL", data: {}}),"http://reciver.com");

reciver.com의 iframe

function listener(event) {
    if (event.origin === "http://sender.com") {
        var data = JSON.parse(event.data);
        $.post(data.url, data.data, function(reponse) {
            window.parent.postMessage(reponse, "*");
        });
    }
}
// don't know if we can use jQuery here
if (window.addEventListener){
    addEventListener("message", listener, false)
} else {
    attachEvent("onmessage", listener)
}

이것은 오래된 질문이지만 일부 새로운 기술은 누군가를 도울 수 있습니다.

다른 서버에 대한 관리 액세스 권한이 있으면 opensource Forge 프로젝트를 사용하여 교차 도메인 POST를 수행 할 수 있습니다. Forge는 Flash의 원시 소켓 API를 이용하는 도메인 간 JavaScript XmlHttpRequest 래퍼를 제공합니다. POST는 TLS를 통해 수행 될 수도 있습니다.

게시하려는 서버에 대한 관리 액세스 권한이 필요한 이유는 도메인에서의 액세스를 허용하는 도메인 간 정책을 제공해야하기 때문입니다.

http://github.com/digitalbazaar/forge


나는 이것이 오래된 질문이라는 것을 알고 있지만 내 접근 방식을 공유하고 싶었습니다. 나는 cURL을 매우 쉽고 일관된 프록시로 사용합니다. submit.php라는 PHP 페이지를 작성하고 다음 코드를 추가하십시오.

<?

function post($url, $data) {
$header = array("User-Agent: " . $_SERVER["HTTP_USER_AGENT"], "Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}

$url = "your cross domain request here";
$data = $_SERVER["QUERY_STRING"];
echo(post($url, $data));

그런 다음 js에서 (jQuery here) :

$.ajax({
type: 'POST',
url: 'submit.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
    var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
    alert('POST failed.');
}
});

YQL 사용자 정의 테이블 + JS XHR로 가능해야합니다. http://developer.yahoo.com/yql/guide/index.html

클라이언트 측 (js) html 긁기를 수행하고 잘 작동합니다 (인터넷 / 재생 목록 / 가사 / 마지막 FM 정보 검색, 모든 클라이언트 js + YQL로 전체 오디오 플레이어가 있음)


CORS는 당신을위한 것입니다. CORS는 "Cross Origin Resource Sharing"이며 도메인 간 요청을 보내는 방법입니다. 이제 XMLHttpRequest2 및 Fetch API는 CORS를 지원하며 POST 및 GET 요청을 모두 보낼 수 있습니다.

그러나 서버는 Access-Control-Allow-Origin 을 구체적으로 요구해야 하며 '*'로 설정할 수 없습니다.

그리고 원점이 요청을 보내려면 JSONP가 필요합니다 ( Access-Control-Allow-Origin 도 설정해야 하지만 '*'일 수 있음)

선택 방법을 모르는 경우 많은 요청 방법을 위해서는 완전한 기능적 구성 요소가 필요하다고 생각합니다. 단순한 구성 요소를 소개하겠습니다 https://github.com/Joker-Jelly/catta


최신 브라우저 (> IE9, Chrome, FF, Edge 등)를 사용하는 경우 단순하지만 아름다운 구성 요소 https://github.com/Joker-Jelly/catta 를 사용하는 것이 좋습니다 . 3KB 이상이며 동일한 치명적인 샘플 구문 및 옵션으로 Fetch, AJAX 및 JSONP를 지원합니다.

catta('./data/simple.json').then(function (res) {
  console.log(res);
});

또한 ES6 모듈, CommonJS 및 <script>HTML 등 프로젝트로 가져 오는 모든 방법을 지원합니다 .


크로스 도메인 서버에 액세스 할 수 있고 서버 측에서 코드를 변경하지 않으려면 'xdomain'이라는 라이브러리를 사용할 수 있습니다.

작동 방식 :

1 단계 : 서버 1 : x 도메인 라이브러리 포함 및 교차 도메인을 슬레이브로 구성

<script src="js/xdomain.min.js" slave="https://crossdomain_server/proxy.html"></script>

2 단계 : 도메인 간 서버에서 proxy.html 파일을 만들고 서버 1을 마스터로 포함합니다.

proxy.html:
<!DOCTYPE HTML>
<script src="js/xdomain.min.js"></script>
<script>
  xdomain.masters({
    "https://server1" : '*'
  });
</script>

3 단계 :

이제 server1에서 엔드 포인트로 proxy.html에 대한 AJAX 호출을 작성할 수 있습니다. 이것은 CORS 요청을 무시합니다. 라이브러리는 내부적으로 자격 증명 및 모든 가능한 방법 (GET, POST 등)과 함께 작동하는 iframe 솔루션을 사용합니다.

쿼리 아약스 코드 :

$.ajax({
        url: 'https://crossdomain_server/proxy.html',
        type: "POST",
        data: JSON.stringify(_data),
        dataType: "json",
        contentType: "application/json; charset=utf-8"
    })
    .done(_success)
    .fail(_failed)

참고 : https://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript



반응형