[javascript] CORS POST 요청은 일반 JavaScript에서 작동하지만 jQuery에서는 작동하지 않는 이유는 무엇입니까?

Cross Origin 게시물 요청을 만들려고하는데 JavaScript다음과 같이 평범하게 작동 합니다.

var request = new XMLHttpRequest();
var params = "action=something";
request.open('POST', url, true);
request.onreadystatechange = function() {if (request.readyState==4) alert("It worked!");};
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);

하지만을 (를) 사용 jQuery하고 싶지만 작동 할 수 없습니다. 이것이 내가 시도하는 것입니다.

$.ajax(url, {
    type:"POST",
    dataType:"json",
    data:{action:"something"},
    success:function(data, textStatus, jqXHR) {alert("success");},
    error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});

이로 인해 실패가 발생합니다. 왜 jQuery작동하지 않는지 아는 사람이 있으면 모두 알려주십시오. 감사.

( jQuery1.5.1 및 Firefox 4.0을 사용하고 있으며 서버가 적절한 Access-Control-Allow-Origin헤더로 응답하고 있습니다 )



답변

업데이트 : TimK가 지적했듯이 jquery 1.5.2에서는 더 이상 필요하지 않습니다. 그러나 사용자 지정 헤더를 추가하거나 자격 증명 (사용자 이름, 암호 또는 쿠키 등) 사용을 허용하려면 계속 읽으십시오.


답을 찾은 것 같아요! (4 시간 후 많은 저주)

//This does not work!!
Access-Control-Allow-Headers: *

수락 할 모든 헤더를 수동으로 지정해야합니다 (적어도 FF 4.0 및 Chrome 10.0.648.204에서 저에게 해당됨).

jQuery의 $ .ajax 메소드는 모든 교차 도메인 요청에 대해 “x-requested-with”헤더를 보냅니다 (나는 유일한 교차 도메인이라고 생각합니다).

따라서 OPTIONS 요청에 응답하는 데 필요한 누락 된 헤더는 다음과 같습니다.

//no longer needed as of jquery 1.5.2
Access-Control-Allow-Headers: x-requested-with

“단순”이 아닌 헤더를 전달하는 경우 목록에 포함해야합니다 (하나 더 보냅니다).

//only need part of this for my custom header
Access-Control-Allow-Headers: x-requested-with, x-requested-by

그래서 그것을 모두 모으기 위해 여기에 내 PHP가 있습니다.

// * wont work in FF w/ Allow-Credentials
//if you dont need Allow-Credentials, * seems to work
header('Access-Control-Allow-Origin: http://www.example.com');
//if you need cookies or login etc
header('Access-Control-Allow-Credentials: true');
if ($this->getRequestMethod() == 'OPTIONS')
{
  header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
  header('Access-Control-Max-Age: 604800');
  //if you need special headers
  header('Access-Control-Allow-Headers: x-requested-with');
  exit(0);
}


답변

또 다른 가능성은 설정으로 dataType: json인해 JQuery가 Content-Type: application/json헤더 를 전송한다는 것 입니다. 이것은 CORS에 의해 비표준 헤더로 간주되며 CORS 프리 플라이트 요청이 필요합니다. 따라서 몇 가지 시도 할 수 있습니다.

1) 적절한 프리 플라이트 응답을 보내도록 서버를 구성하십시오. 이 같은 추가 헤더의 형태로 될 것입니다 Access-Control-Allow-MethodsAccess-Control-Allow-Headers.

2) dataType: json설정을 삭제합니다 . JQuery는 Content-Type: application/x-www-form-urlencoded기본적으로 요청해야 하지만 확실히하기 위해 다음 dataType: json으로 대체 할 수 있습니다.contentType: 'application/x-www-form-urlencoded'


답변

js에서 “params”를 보내고 있습니다.
request.send(params);

그러나 jquery의 “data”. 데이터가 정의되어 있습니까? :
data:data,

또한 URL에 오류가 있습니다.

$.ajax( {url:url,
         type:"POST",
         dataType:"json",
         data:data,
         success:function(data, textStatus, jqXHR) {alert("success");},
         error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});

$ .post에 대한 구문과 구문을 혼합하고 있습니다.


업데이트 : monsur 답변을 기반으로 검색 중이며 추가해야 함을 발견했습니다 Access-Control-Allow-Headers: Content-Type(아래는 전체 단락입니다)

http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/

CORS 작동 방식

CORS는 Flash의 crossdomain.xml 파일과 매우 유사하게 작동합니다. 기본적으로 브라우저는 HTTP 헤더 Origin을 요청 서버로 설정하여 크로스 도메인 요청을 서비스에 보냅니다. 이 서비스에는 그러한 요청이 허용되는지 여부를 나타내는 Access-Control-Allow-Origin과 같은 몇 가지 헤더가 포함되어 있습니다.

BOSH 연결 관리자의 경우 Access-Control-Allow-Origin 값을 *로 설정하여 모든 출처가 허용되도록 지정하는 것으로 충분합니다. Content-Type 헤더는 Access-Control-Allow-Headers 헤더에서도 허용 목록에 포함되어야합니다.

마지막으로 BOSH 연결 관리자 요청을 포함한 특정 유형의 요청에 대해 권한 검사가 사전에 수행됩니다. 브라우저는 OPTIONS 요청을 수행하고 어떤 출처가 허용되는지, 어떤 메소드가 허용되는지,이 권한이 얼마나 오래 지속되는지를 나타내는 일부 HTTP 헤더를 반환 할 것으로 예상합니다. 예를 들어 다음은 내가 OPTIONS에 대해 반환 한 Punjab 및 ejabberd 패치입니다.

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400


답변

Cors는 요청 방법을 완료하기 전에 POST에서 OPTIONS로 변경하므로 게시 데이터가 전송되지 않습니다. 이 cors 문제를 처리하기 위해 일한 방법은 OPTIONS 메서드를 지원하지 않는 ajax로 요청을 수행하는 것입니다. 예제 코드 :

        $.ajax({
            type: "POST",
            crossdomain: true,
            url: "http://localhost:1415/anything",
            dataType: "json",
            data: JSON.stringify({
                anydata1: "any1",
                anydata2: "any2",
            }),
            success: function (result) {
                console.log(result)
            },
            error: function (xhr, status, err) {
                console.error(xhr, status, err);
            }
        });

C # 서버에서이 헤더로 :

                    if (request.HttpMethod == "OPTIONS")
                    {
                          response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
                          response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
                          response.AddHeader("Access-Control-Max-Age", "1728000");
                    }
                    response.AppendHeader("Access-Control-Allow-Origin", "*");


답변

다음과 같은 방법으로 Jquery를 수정하십시오.

$.ajax({
            url: someurl,
            contentType: 'application/json',
            data: JSONObject,
            headers: { 'Access-Control-Allow-Origin': '*' }, //add this line
            dataType: 'json',
            type: 'POST',
            success: function (Data) {....}
});


답변