JavaScript를 통해 도메인 간 POST 요청을 보내려면 어떻게합니까?
참고-페이지를 새로 고치면 안되며 나중에 응답을 잡고 구문 분석해야합니다.
JavaScript를 통해 도메인 간 POST 요청을 보내려면 어떻게합니까?
참고-페이지를 새로 고치면 안되며 나중에 응답을 잡고 구문 분석해야합니다.
답변:
업데이트 : 계속하기 전에 모든 사람이 CORS에 대한 html5rocks 튜토리얼 을 읽고 이해해야합니다 . 이해하기 쉽고 매우 명확합니다.
POST중인 서버를 제어하는 경우 서버에서 응답 헤더를 설정하여 "Cross-Origin Resource Sharing 표준"을 활용하십시오. 이 답변은이 스레드의 다른 답변에서 논의되지만 내 의견으로는 명확하지 않습니다.
간단히 말해서 from.com/1.html에서 to.com/postHere.php (예를 들어 PHP를 사용하여)로 교차 도메인 POST를 수행하는 방법이 있습니다. 참고 : Access-Control-Allow-Origin
NON OPTIONS
요청에 대해서만 설정하면됩니다. 이 예에서는 항상 더 작은 코드 스 니펫에 대해 모든 헤더를 설정합니다.
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를 만들 수 있습니다. 계속 읽으면서 이것은 분명해질 것입니다 ...
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에서만 작동하는지 확인했습니다.
이렇게하면 다음을 명심하십시오.
400 Bad Request
에 OPTIONS
요청. 그리고 firefox
두 번째 요청에서 POST
결코 이루어지지 않습니다. :(
원격 서버를 제어하는 경우이 답변에 설명 된대로 CORS를 사용해야합니다 . IE8 이상 및 모든 최신 버전의 FF, GC 및 Safari에서 지원됩니다. 그러나 IE8 및 9에서는 CORS에서 요청에 쿠키를 보낼 수 없습니다.
따라서 원격 서버를 제어 하지 않거나 IE7을 지원해야하거나 쿠키가 필요하고 IE8 / 9를 지원해야하는 경우 iframe 기술을 사용하고 싶을 것입니다.
샘플 코드는 다음과 같습니다. 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 기간의 응답을 읽을 수 없습니다. 그렇지 않으면 보안 문제가 발생할 수 있습니다.
의사 코드
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 스타일을 지정하고 싶을 것입니다. 브라우저에서 교차 사이트 게시가 허용되는지 확실하지 않지만 그렇게하는 경우이를 수행하는 방법입니다.
간단하게 유지하십시오.
도메인 간 POST :
사용crossDomain: true,
페이지를 새로 고치면 안됩니다.
아니요,서버가 응답을 다시 보낼 때success
또는error
비동기 콜백이 호출되므로페이지를 새로 고치지 않습니다.
$.ajax({
type: "POST",
url: "http://www.yoururl.com/",
crossDomain: true,
data: 'param1=value1¶m2=value2',
success: function (data) {
// do something with server response data
},
error: function (err) {
// handle your error logic here
}
});
crossDomain: true
이상하게도 실제 도메인 간 요청과는 전혀 관련이 없습니다. 요청이 도메인 간인 경우 jquery는이를 자동으로 true로 설정합니다.
관련된 모든 서버에 액세스 할 수있는 경우 다른 도메인에서 요청중인 페이지의 회신 헤더에 다음을 입력하십시오.
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.js 의 post_method
기능을 확인하십시오 .
두 개의 숨겨진 iframe을 만듭니다 (css 스타일에 "display : none;"추가). 두 번째 iframe이 자신의 도메인에있는 무언가를 가리 키도록합니다.
숨겨진 양식을 만들고 target = 첫 번째 iframe으로 메소드를 "post"로 설정하고 선택적으로 enctype을 "multipart / form-data"로 설정합니다 (그림과 같은 여러 부분으로 데이터를 보내려고하므로 POST를 수행하려고합니다. ?)
준비되면, submit () 양식을 POST로 만드십시오.
다른 도메인에서 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 응용 프로그램)에 게시되어야한다고 가정합니다.
"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>
"server.com"에서 우리는 게시 할 컨트롤러 ( "Home")에 대해 다음과 같은 작업을 수행합니다.
[HttpPost]
public JsonResult Save()
{
//Handle the post data...
return Json(
new
{
IsSuccess = true
});
}
그런 다음 "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
}
});
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)
}
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
이것은 오래된 질문이지만 일부 새로운 기술은 누군가를 도울 수 있습니다.
다른 서버에 대한 관리 액세스 권한이 있으면 opensource Forge 프로젝트를 사용하여 교차 도메인 POST를 수행 할 수 있습니다. Forge는 Flash의 원시 소켓 API를 이용하는 도메인 간 JavaScript XmlHttpRequest 래퍼를 제공합니다. POST는 TLS를 통해 수행 될 수도 있습니다.
게시하려는 서버에 대한 관리 액세스 권한이 필요한 이유는 도메인에서의 액세스를 허용하는 도메인 간 정책을 제공해야하기 때문입니다.
나는 이것이 오래된 질문이라는 것을 알고 있지만 내 접근법을 공유하고 싶었습니다. 나는 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)