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요청에 대해서만 설정하면됩니다. 이 예에서는 항상 더 작은 코드 스 니펫에 대해 모든 헤더를 설정합니다.
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)