Programing

CORS POST 요청은 일반 자바 스크립트에서 작동하지만 jQuery에서는 작동하지 않는 이유는 무엇입니까?

lottogame 2020. 9. 25. 08:14
반응형

CORS POST 요청은 일반 자바 스크립트에서 작동하지만 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가 작동하지 않는 이유를 아는 사람이 있으면 모두 알려주십시오. 감사.

(jQuery 1.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) Try configuring your server to send the proper preflight responses. This will be in the form of additional headers like Access-Control-Allow-Methods and Access-Control-Allow-Headers.

2) Drop the dataType: json setting. JQuery should request Content-Type: application/x-www-form-urlencoded by default, but just to be sure, you can replace dataType: json with contentType: 'application/x-www-form-urlencoded'


You are sending "params" in js: request.send(params);

but "data" in jquery". Is data defined?: data:data,

Also, you have an error in the URL:

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

You are mixing the syntax with the one for $.post


Update: I was googling around based on monsur answer, and I found that you need to add Access-Control-Allow-Headers: Content-Type (below is the full paragraph)

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

How CORS Works

CORS works very similarly to Flash's crossdomain.xml file. Basically, the browser will send a cross-domain request to a service, setting the HTTP header Origin to the requesting server. The service includes a few headers like Access-Control-Allow-Origin to indicate whether such a request is allowed.

For the BOSH connection managers, it is enough to specify that all origins are allowed, by setting the value of Access-Control-Allow-Origin to *. The Content-Type header must also be white-listed in the Access-Control-Allow-Headers header.

Finally, for certain types of requests, including BOSH connection manager requests, the permissions check will be pre-flighted. The browser will do an OPTIONS request and expect to get back some HTTP headers that indicate which origins are allowed, which methods are allowed, and how long this authorization will last. For example, here is what the Punjab and ejabberd patches I did return for OPTIONS:

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

Cors change the request method before it's done, from POST to OPTIONS, so, your post data will not be sent. The way that worked to handle this cors issue, is performing the request with ajax, which does not support the OPTIONS method. example code:

        $.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);
            }
        });

with this headers on c# server:

                    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", "*");

Modify your Jquery in following way:

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

참고URL : https://stackoverflow.com/questions/5584923/a-cors-post-request-works-from-plain-javascript-but-why-not-with-jquery

반응형