developer tip

Chrome의 AJAX가 GET / POST / PUT / DELETE 대신 옵션을 전송합니까?

copycodes 2020. 8. 19. 19:46
반응형

Chrome의 AJAX가 GET / POST / PUT / DELETE 대신 옵션을 전송합니까?


직장에서 내부 웹 응용 프로그램을 작업 중입니다. IE10에서는 요청이 제대로 작동하지만 Chrome에서는 모든 AJAX 요청 (많은 경우)이 내가 제공하는 정의 된 방법 대신 OPTIONS를 사용하여 전송됩니다. 기술적으로 내 요청은 "교차 도메인"입니다. 이 사이트는 localhost : 6120에서 제공되며 AJAX 요청을하는 서비스는 57124에 있습니다. 이 닫힌 jquery 버그 는 문제를 정의하지만 실제 수정은 아닙니다.

ajax 요청에서 적절한 http 메소드를 사용하려면 어떻게해야합니까?

편집하다:

이것은 모든 페이지의 문서로드에 있습니다.

jQuery.support.cors = true;

그리고 모든 AJAX는 유사하게 구축됩니다.

var url = 'http://localhost:57124/My/Rest/Call';
$.ajax({
    url: url,
    dataType: "json",
    data: json,
    async: true,
    cache: false,
    timeout: 30000,
    headers: { "x-li-format": "json", "X-UserName": userName },
    success: function (data) {
        // my success stuff
    },
    error: function (request, status, error) {
        // my error stuff
    },
    type: "POST"
});

Chrome은 CORS 헤더 를 찾는 요청을 프리 플라이트하고 있습니다. 요청이 허용되면 실제 요청을 보냅니다. 이 교차 도메인을 수행하는 경우 단순히 처리하거나 요청을 비 교차 도메인으로 만드는 방법을 찾아야합니다. 이것이 jQuery 버그가 수정되지 않는 것처럼 닫힌 이유입니다. 이것은 의도적으로 설계된 것입니다.

간단한 요청 (위에서 설명)과 달리 "프리 플라이트 된"요청은 실제 요청을 보내는 것이 안전한지 여부를 확인하기 위해 먼저 OPTIONS 메서드에 의해 다른 도메인의 리소스에 HTTP 요청을 보냅니다. 교차 사이트 요청은 사용자 데이터에 영향을 미칠 수 있으므로 이와 같이 미리 실행됩니다. 특히 다음과 같은 경우 요청이 프리 플라이트됩니다.

  • GET, HEAD 또는 POST 이외의 방법을 사용합니다. 또한 POST를 사용하여 application / x-www-form-urlencoded, multipart / form-data 또는 text / plain 이외의 Content-Type으로 요청 데이터를 보내는 경우 (예 : POST 요청이 서버에 XML 페이로드를 보내는 경우) application / xml 또는 text / xml을 사용하면 요청이 프리 플라이트됩니다.
  • 요청에 사용자 정의 헤더를 설정합니다 (예 : 요청이 X-PINGOTHER와 같은 헤더를 사용함).

요청 이 기본 포트 80/443에서 전송되지 않는다는 사실을 기반 으로이 Ajax 호출은 자동으로 CORS (Cross-Origin Resource) 요청으로 간주됩니다. 즉, 요청이 다음을 확인하는 OPTIONS 요청을 자동으로 발행 함을 의미합니다. 서버 / 서블릿 측의 CORS 헤더.

이것은 당신이 설정 한 경우에도 발생합니다

crossOrigin: false;

또는 생략하더라도.

그 이유는 단순히 localhost != localhost:57124. localhost포트없이 전송 해보 십시오. 요청 된 대상에 도달 할 수 없기 때문에 실패합니다. 그러나 도메인 이름이 같으면 POST 전에 OPTIONS 요청없이 요청이 전송됩니다.


나는 Kevin B에 동의합니다. 버그 보고서에 모든 것이 나와 있습니다. 도메인 간 ajax 호출을 시도하는 것 같습니다. 동일한 출처 정책에 익숙하지 않은 경우 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript에서 시작할 수 있습니다 .

이것이 교차 도메인 아약스 호출이 아닌 경우 대상 URL을 상대적으로 만들고 문제가 해결되는지 확인하십시오. JSONP를 절실히 들여다보고 있지만 조심하면 혼란이 숨어 있습니다. 당신을 돕기 위해 우리가 할 수있는 일이별로 없습니다.


가능하다면 다른 이름의 일반 GET / POST를 통해 매개 변수를 전달하고 서버 측 코드에서 처리하도록합니다.

CORS를 우회하기 위해 내 프록시와 비슷한 문제가 있었고 Chrome에서 POST-> OPTION과 동일한 오류가 발생했습니다. 그것은 Authorization내 경우 헤더 였습니다 ( "x-li-format"그리고 "X-UserName"귀하의 경우에는 여기에 있습니다.) 결국 더미 형식 (예 : AuthorizatinJackGET)으로 전달했고 목적지에 대한 호출을 할 때 프록시의 코드를 헤더로 바꾸도록 변경했습니다. . 다음은 PHP입니다.

if (isset($_GET['AuthorizationJack'])) {
    $request_headers[] = "Authorization: Basic ".$_GET['AuthorizationJack'];
}

제 경우에는 AWS (API Gateway)에서 호스팅하는 API를 호출하고 있습니다. API 자체 도메인이 아닌 다른 도메인에서 API를 호출하려고 할 때 오류가 발생했습니다. 저는 API 소유자이므로 Amazon 설명서에 설명 된대로 테스트 환경에 대해 CORS를 활성화했습니다 .

프로덕션에서는 요청과 API가 동일한 도메인에 있기 때문에이 오류가 발생하지 않습니다.

도움이 되었기를 바랍니다.


으로 대답 @Dark 팔콘, 나는 간단하게 처리 .

제 경우에는 node.js 서버를 사용하고 있고 존재하지 않으면 세션을 생성합니다. OPTIONS 메서드에는 세션 세부 정보가 없기 때문에 모든 POST 메서드 요청에 대해 새 세션이 생성되었습니다.

So in my app routine to create-session-if-not-exist, I just added a check to see if method is OPTIONS, and if so, just skip session creating part:

    app.use(function(req, res, next) {
        if (req.method !== "OPTIONS") {
            if (req.session && req.session.id) {
                 // Session exists
                 next();
            }else{
                 // Create session
                 next();
          }
        } else {
           // If request method is OPTIONS, just skip this part and move to the next method.
           next(); 
        }
    }

"preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS


Consider using axios

axios.get( url,
{ headers: {"Content-Type": "application/json"} } ).then( res => {

  if(res.data.error) {

  } else { 
    doAnything( res.data )
  }

}).catch(function (error) {
   doAnythingError(error)
});

I had this issue using fetch and axios worked perfectly.


I've encountered a very similar issue. I spent almost half a day to understand why everything works correctly in Firefox and fails in Chrome. In my case it was because of duplicated (or maybe mistyped) fields in my request header.


 $.ajax({
            url: '###',
            contentType: 'text/plain; charset=utf-8',
            async: false,
            xhrFields: {
                withCredentials: true,
                crossDomain: true,
                Authorization: "Bearer ...."
            },

            method: 'POST',

            data: JSON.stringify( request ),
            success: function (data) {
                console.log(data);
            }
        });

the contentType: 'text/plain; charset=utf-8', or just contentType: 'text/plain', works for me! regards!!

참고URL : https://stackoverflow.com/questions/21783079/ajax-in-chrome-sending-options-instead-of-get-post-put-delete

반응형