jQuery.ajax에서 콘텐츠 유형을 'application / json'으로 설정할 수 없습니다.


106

이 코드가있을 때

$.ajax({
    type: 'POST',
    //contentType: "application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: 'json'
});

Fiddler에서 다음 원시 요청을 볼 수 있습니다.

POST http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:14693/WebSite1/index.html
Content-Length: 9
Origin: http://localhost:14693
Pragma: no-cache
Cache-Control: no-cache

name=norm

하지만 내가하려는 것은 application / x-www-form-urlencoded 에서 application / json으로 content-type을 설정하는 것입니다 . 하지만이 코드

$.ajax({
    type: "POST",
    contentType: "application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: "json"
});

이상한 요청을 생성합니다 (Fiddler에서 볼 수 있음).

OPTIONS http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: http://localhost:14693
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Pragma: no-cache
Cache-Control: no-cache

왜 그런 겁니까? POST가 필요한 경우 OPTIONS는 무엇입니까? 내 콘텐츠 유형은 어디에 application / json으로 설정되어 있습니까? 그리고 어떤 이유로 요청 매개 변수가 사라졌습니다.

업데이트 1

서버 측에는 정말 간단한 RESTful 서비스가 있습니다.

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestfulService : IRestfulService
{
    [WebInvoke(
        Method = "POST",
        UriTemplate = "Hello",
        ResponseFormat = WebMessageFormat.Json)]
    public string HelloWorld(string name)
    {
        return "hello, " + name;
    }
}

그러나 어떤 이유로이 메서드를 매개 변수로 호출 할 수 없습니다.

업데이트 2

너무 오래 응답하지 않아서 죄송합니다.

이 헤더를 내 서버 응답에 추가했습니다.

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

도움이되지 않았습니다. Method not allowed error from server가 있습니다.

여기 내 피들러가하는 말

여기에 이미지 설명 입력

이제 내 서버가 POST, GET, OPTIONS를 수락하는지 확인할 수 있습니다 (응답 헤더가 예상대로 작동하는 경우). 그러나 왜 "방법이 허용되지 않습니까?"

서버의 WebView 응답 ( 위 그림에서 원시 응답을 볼 수 있음 )은 다음과 같습니다.

여기에 이미지 설명 입력


2
당신은 JSON.stringfy () 메소드를 시도해야
— 암릿 펄 싱에게

이봐. 이것은 아주 잘 나를 위해 작동 : stackoverflow.com/questions/9754767/...
— Fanda

나는 똑같은 문제가 있지만 NodeJS를 백엔드로 사용하고 있으며 모든 OPTION 요청을 수락 할뿐만 아니라 모든 OPTION 요청에 대해 200 응답을 강제로 설정하여 나머지 청원이 예상대로 작동합니다. 응답이와 ...
— HeberLZ

1
안녕하세요 @VitaliiKorsakov. 문제를 해결 했습니까? 동일한 문제가 발생합니다. 즉, contentType을 수정할 수 없습니다.
— worldterminator

1
나는 똑같은 문제가 있었고 방금 작동했습니다 .. 해결책은이 페이지의 답변에 있습니다. stackoverflow.com/questions/20295080/… .. 요약 : "contentType : 'application / json'을 사용할 때 $ _POST가 채워지는 것에 의존 할 수 없습니다. $ _POST는 양식 인코딩 된 콘텐츠 유형에 대해서만 채워집니다. 따라서 PHP 원시 입력에서 데이터를 읽어야합니다. ". 이제 서버에서 php를 사용하고 있지 않습니다. 이 정보가 도움이되기를 바랍니다.
— Sarah

답변:


91

http://url 옵션에서 제거 하면 올바른 HTTP POST 헤더가 전송되는 것 같습니다.

나는 당신이 호스트의 이름을 완전히 규정 할 필요가 없다고 생각합니다. 단지 아래와 같이 상대 URL을 사용하십시오.

   $.ajax({
      type: "POST",
      contentType: "application/json",
      url: '/Hello',
      data: { name: 'norm' },
      dataType: "json"
   });

작동하는 내 예 :

        $.ajax({
            type: "POST",
            url: siteRoot + "api/SpaceGame/AddPlayer",
            async: false,
            data: JSON.stringify({ Name: playersShip.name, Credits: playersShip.credits }),
            contentType: "application/json",
            complete: function (data) {
            console.log(data);
            wait = false;
        }
    });

관련 가능성이있는 경우 : jQuery $ .ajax (), $ .post가 Firefox에서 REQUEST_METHOD로 "OPTIONS"를 전송 함

편집 : 좀 더 조사한 후 OPTIONS 헤더가 원래 도메인의 요청이 허용되는지 확인하는 데 사용된다는 것을 알았습니다. 피들러를 사용하여 서버의 응답 헤더에 다음을 추가했습니다.

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

브라우저가이 응답을 수신하면 json 데이터와 함께 올바른 POST 요청을 보냈습니다. 기본 form-urlencoded 콘텐츠 유형은 안전한 것으로 간주되어 추가 교차 도메인 검사를 거치지 않는 것 같습니다.

OPTIONS 요청에 대한 응답으로 앞서 언급 한 헤더를 서버에 추가해야 할 것 같습니다. 물론 전체가 아닌 특정 도메인의 요청을 허용하도록 구성해야합니다.

이것을 테스트하기 위해 다음 jQuery를 사용했습니다.

$.ajax({
   type: "POST",
   url: "http://myDomain.com/path/AddPlayer",
   data: JSON.stringify({
      Name: "Test",
       Credits: 0
   }),
   //contentType: "application/json",
   dataType: 'json',
   complete: function(data) {
       $("content").html(data);
  }
});​

참조 :


클라이언트와 서버 간의 결합을 풀고 싶습니다. 서버는 RESTful 서비스이며이 서비스의 모든 클라이언트는 URL을 알아야합니다.
— Vitalii Korsakov는

이 질문의 시나리오에 대한 자세한 내용을 게시물에 제공 할 수 있습니까? 클라이언트가 다른 도메인에있을 경우 동일한 원본 문제가 발생할 수 있습니다.
— Mike Wade

서버 측에 대한 추가 정보를 게시했습니다. 현재 서버와 클라이언트는 모두 localhost에 있지만 포트가 다릅니다. 나중에 그들은 다른 도메인에있을 가능성이 큽니다.
— Vitalii Korsakov

귀하가 경험하는 문제는 동일한 출처 정책과 관련된 것 같습니다 . 이 링크 관련 질문 외에도 jsonp 및 내 답변에서 링크 한 질문을 살펴볼 가치가 있습니다 . jquery 크로스 도메인 가이드 -크로스 도메인 요청에 대한 경험이 많지 않지만 해당 링크가 유용 할 것입니다.
— Mike Wade

매개 변수를 전달하지 않고 콘텐츠 유형이 application / x-www-form-urlencoded 일 때 모든 것이 잘 작동하기 때문에 이것이 문제라고 생각하지 않습니다. 그러나 매개 변수를 전달할 수 없으면 POST 요청이 필요하지 않습니다.
— Vitalii Korsakov

41

어떻게 사용했는지 보여 드릴 수 있습니다

  function GetDenierValue() {
        var denierid = $("#productDenierid").val() == '' ? 0 : $("#productDenierid").val();
        var param = { 'productDenierid': denierid };
        $.ajax({
            url: "/Admin/ProductComposition/GetDenierValue",
            dataType: "json",
            contentType: "application/json;charset=utf-8",
            type: "POST",
            data: JSON.stringify(param),
            success: function (msg) {
                if (msg != null) {
                    return msg.URL;
                }
            }
        });
    }

다음 답변과 동일합니다. 나는 모든 서비스 기능을 호스팅하는 서버에 URL을 지정하지 없습니다
— Vitalii 코르사코프

@VitaliiKorsakov 내가 떠났어, 문제를 해결 했습니까?
— Amritpal Singh 2012

답변 해주셔서 감사합니다! 나는 이것이 다른 곳에서 철자가 없다는 것을 믿을 수 없다. 지정하는 유형이 'json'일 때 JQuery가 json을 게시하는 것처럼 보이지만, 제 생각에는 ...
— Jason Goemaat

1
@JasonGoemaat jQuery의 dataType 매개 변수는 반환 된 응답 본문을 구문 분석하는 데만 사용됩니다. 문서를 읽으면 필요하지 않다는 것을 알 수 있습니다. dataType의 기본값은 지능형 추측입니다. 문제는 jquery의 데이터 속성을 구성 할 수 없다는 것입니다. jquery가 데이터 객체를 구문 분석하는 방법을 알 수 없습니다. 이것이 이전에 json을 직렬화해야하는 이유입니다. jquery는 url-form-encode로만 직렬화되기 때문에
— Loïc Faure-Lacroix 2013 년

12

따라서이 작업을 수행하려면 다음을 추가하면됩니다.

headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
}

게시물 요청에 대한 필드로 작동합니다.


api.jquery.com/jquery.ajax 문서를 보면 지정하지 않으면 기본적으로 'application / x-www-form-urlencoded; charset = UTF-8 '(이것이 발생하는 이유입니다. Idk는 contentType을 설정해도 작동하지 않는 이유입니다. 사용중인 jQuery 버전을 확인하고 이전 버전 인 경우 업데이트 할 수 있습니다.)
— Cody Jacques

이것은 작동하지 않습니다. 내가 가지고 있지만 type: "POST", 그것은 보내는 것 OPTIONS입니다.
— user9645

5

나는 그 화면을 인식하고 CodeFluentEntities를 사용하고 있으며 저에게도 효과가있는 솔루션이 있습니다.

나는 그 구조를 사용하고 있습니다.

$.ajax({
   url: path,
   type: "POST",
   contentType: "text/plain",
   data: {"some":"some"}
}

보시다시피, 내가 사용한다면

contentType: "",

또는

contentType: "text/plain", //chrome

모든 것이 잘 작동합니다.

헤더도 변경했기 때문에 필요한 모든 것이 100 % 확실하지 않습니다.


5

이것을 사용하는 경우 :

contentType: "application/json"

AJAX는 서버에 GET 또는 POST 매개 변수를 보내지 않습니다 .... 이유를 모릅니다.

오늘 그것을 훑어 보는 데 몇 시간이 걸렸습니다.

그냥 사용 :

$.ajax(
  { url : 'http://blabla.com/wsGetReport.php',
    data : myFormData, type : 'POST', dataType : 'json', 
    // contentType: "application/json", 
    success : function(wsQuery) { }
  }
)

1
슬프게도 정답입니다. contentType을 생략하고 dataType을 사용하여 많은 서비스가 제대로 구현하지 않는 CORS OPTIONS 쓰레기를 우회하십시오. 너무 짜증나.
— Umopepisdn

2

나는이 문제에 대한 해결책을 찾을 여기를 . IIS 앱 서비스 핸들러에서 동사 OPTIONS를 허용하는 것을 잊지 마십시오.

잘 작동합니다. André Pedroso 감사합니다. :-)


1

나는 같은 문제가 있었다. jboss 서버에서 자바 휴식 앱을 실행하고 있습니다. 그러나 솔루션은 ASP .NET 웹 응용 프로그램과 유사하다고 생각합니다.

Firefox는 허용되는 옵션을 확인하기 위해 서버 / 나머지 URL을 미리 호출합니다. 그것은 서버가 그에 따라 응답하지 않는 "OPTIONS"요청입니다. 이 OPTIONS 호출이 올바르게 응답되면 json 콘텐츠가 포함 된 실제 "POST"요청 인 두 번째 호출이 수행됩니다.

이것은 교차 도메인 호출을 수행 할 때만 발생합니다. 귀하의 경우 http://localhost:16329/Hello동일한 도메인 '/ Hello'에서 URL 경로를 호출하는 대신 ' '를 호출하십시오.

도메인 간 호출을하려는 경우 "OPTIONS"http 요청을 지원하는 어노테이션이있는 메소드로 나머지 서비스 클래스를 향상시켜야합니다. 다음은 해당 자바 구현입니다.

@Path("/rest")
public class RestfulService {

    @POST
    @Path("/Hello")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.TEXT_PLAIN)
    public string HelloWorld(string name)
    {
        return "hello, " + name;
    }

//THIS NEEDS TO BE ADDED ADDITIONALLY IF MAKING CROSS-DOMAIN CALLS

    @OPTIONS
    @Path("/Hello")
    @Produces(MediaType.TEXT_PLAIN+ ";charset=utf-8")
    public Response checkOptions(){
        return Response.status(200)
        .header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "Content-Type")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS") //CAN BE ENHANCED WITH OTHER HTTP CALL METHODS 
        .build();
    }
}

그래서 .NET에서 주석이 달린 추가 메서드를 추가해야한다고 생각합니다.

[WebInvoke(
        Method = "OPTIONS",
        UriTemplate = "Hello",
        ResponseFormat = WebMessageFormat.)]

다음 헤더가 설정된 위치

.header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "Content-Type")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS")

0

jquery ajax를 통해 POST 요청으로 JSON 데이터를 보내는 솔루션이 있습니다. 나는 아래 코드를 사용했다

    var data = new Object();
    data.p_clientId = 4;
    data =  JSON.stringify(data);

    $.ajax({
      method: "POST",
      url: "http://192.168.1.141:8090/api/Client_Add",
      data: data,
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'text/plain'
    }
    })
      .done(function( msg ) {
        alert( "Data Saved: " + msg );
      });


        });
    });

'Content-Type': 'text/plain'원시 json 데이터를 보내기 위해 헤더에 사용 했습니다.
우리가 사용하는 경우 때문에 Content-Type: 'application/json'방법은 OPTION로 변환 요청을하지만, 사용 Content-Type: 'test/plain'방법은 변환 얻을 POST로 남아 있지 않습니다. 바라건대 이것은 누군가를 도울 것입니다.


3
실제로 OPTION으로 변환되지 않고 POST가 허용되는지 확인하기 위해 CORS 프리 플라이트 요청을 보냅니다. 이것이 제대로 돌아 오지 않으면 POST가 발생하지 않습니다.
— Umopepisdn

0

안녕이 두 줄은 나를 위해 일했습니다.

contentType : "application / json; charset = utf-8", dataType : "json"

 $.ajax({
            type: "POST",
            url: "/v1/candidates",
            data: obj,
            **contentType:"application/json; charset=utf-8",
            dataType:"json",**
            success: function (data) {
                table.row.add([
                    data.name, data.title
                ]).draw(false);
            }

감사합니다, Prashant

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.