programing

Ajax를 통해 게시를 수행할 때 JSON 결과 대신 Bad Request가 반환됩니다.

mytipbox 2023. 8. 26. 16:25
반응형

Ajax를 통해 게시를 수행할 때 JSON 결과 대신 Bad Request가 반환됩니다.

자바스크립트

jqXHR = $.ajax({ url: $frm.attr("action"), type: "POST", dataType: "json", cache: false,
  headers: headers, contentType: "application/json;charset=UTF-8", data: ko.mapping.toJSON(data, map),
  beforeSend: function(x) {
    if (x && x.overrideMimeType) {
      return x.overrideMimeType("application/json;charset=UTF-8");
    }
  }
});

jqXHR.fail(function(xhr, err, msg) {  /* xhr.responseText  NEED TO BE JSON!!! */ });

In Chrome

머리글

Request Method:POST
Status Code:400 Bad Request
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,pt-BR;q=0.6,pt;q=0.4
Connection:keep-alive
Content-Length:10
Content-Type:application/json;charset=UTF-8
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36
X-Requested-With:XMLHttpRequest
Request Payloadview source {Id:0}
Response Headersview source
Cache-Control:private
Content-Length:54
Content-Type:application/json; charset=utf-8
Date:Thu, 27 Feb 2014 14:01:59 GMT
Server:Microsoft-IIS/8.0
X-AspNet-Version:4.0.30319
X-AspNetMvc-Version:5.1
X-Powered-By:ASP.NET

대답

[{"이름":"아니오", "오류 메시지": "캄포 오브리가토리오""}]

크롬으로 작동합니다!


IE8에서

머리글(요청)

POST /Motivos/Salvar HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: pt-br
x-requested-with: XMLHttpRequest
Content-Type: application/json;charset=UTF-8
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)
Content-Length: 10
Connection: Keep-Alive
Pragma: no-cache

머리글(응답)

HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 5.1
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 27 Feb 2014 13:51:46 GMT
Content-Length: 11

Bad Request

작동하지 않습니다!!

Asp.net MVC

필터

public class HandleExceptionAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
        {
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            var ex = filterContext.Exception.GetBaseException();
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    ex.Message,
                    ex.GetType().Name
                }
            };
            filterContext.ExceptionHandled = true;
        }
        else
        {
            base.OnException(filterContext);
        }
    }
}

GlobalFilterCollection에 적용

컨트롤러

[ValidateJsonAntiForgeryToken, HttpPost]
public virtual JsonResult Salvar(TViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        TEntity model;
        if (default(TKey).Equals(viewModel.Id))
        {
            model = Mapper.Map<TEntity>(viewModel);
            AdicionarEntidade(model, viewModel);
        }
        else
        {
            model = Repositorio.Get(viewModel.Id);
            Mapper.Map(viewModel, model, typeof(TViewModel), typeof(TEntity));
            SalvarEntidade(model, viewModel);
        }

        return SalvarResult(model);
    }

    Response.StatusCode = 400;
    return Json(ModelState.ToJson(), JsonRequestBehavior.AllowGet);
}

확장

public static object ToJson(this ModelStateDictionary dic, params string[] othersMessages)
{
    var states = (from e in dic where e.Value.Errors.Count > 0
                  select new { Name = e.Key, e.Value.Errors[0].ErrorMessage }).ToList();

    if (othersMessages != null)
        foreach (var message in othersMessages)
            states.Add(new { Name = "", ErrorMessage = message });

    return states;
}

문의사항

  • 왜 xhr.resposure를 사용하지 않습니까?텍스트 개체?
  • 크롬에서 복구하는 것과 같은 방식으로 JSON을 검색하는 방법은 무엇입니까?

양식을 작성하려면 JSON이 필요합니다!

참고사항: 2014년 3월 11일

추가할 때Response.TrySkipIisCustomErrors = true;내 컨트롤러에서는 작동합니다! responseText는 json을 반환합니다. 왜죠?

IIS에서 컨트롤러가 생성하는 오류 메시지를 보내는 대신 사용자 지정 오류 응답을 사용하려고 하는 문제라고 생각합니다.

<system.webServer>
    ...
    <httpErrors existingResponse="PassThrough"></httpErrors>
    ...
</system.webServer>

또는

Response.TrySkipIisCustomErrors = true;

참조 - https://stackoverflow.com/a/4029197/1304559

이 블로그 게시물 http://weblog.west-wind.com/posts/2009/Apr/29/IIS-7-Error-Pages-taking-over-500-Errors 을 확인해 보세요.

응답 코드가 400으로 설정되어 있으므로 IIS는 사용자 정의 오류 페이지 내용으로 내용을 바꿉니다.

문제는 당신이 JSON 인코딩을 UTF-8로 설정하려고 한다는 것입니다. 일반적으로 정상적으로 작동하지만 IIS에서는 UTF-8이 필요하지 않다고 보고하는 사용자 정의 오류가 있습니다.

그 밖에 몇 가지 주의할 점이 있습니다.POST를 수행 중이므로 서버에서 json 파일이 필요합니다.아무것도 제공되지 않으면 어떻게 해야 할지 알 수 없습니다.

응답 내용은 다음과 같습니다.Content-Type: text/htmlhttp 헤더, 하지만 그래야 합니다.application/jsonChrome에서는 문제가 되지 않습니다(콘솔에서 불일치 경고가 표시되지 않습니다). 사용자가 필요하기 때문입니다.짐작하셨겠지만, 그건 IE에 우호적이지 않습니다.실제로 다음은 이전 버전의 IE에서는 실행되지 않습니다.

if (x && x.overrideMimeType) {
  return x.overrideMimeType("application/json;charset=UTF-8");
}

해결책은 콘텐츠가 올바른 콘텐츠 유형으로 제공되는지 확인하는 것일 수 있습니다.Burp Suite와 같은 변조 도구에 익숙하다면 올바른 헤더를 즉시 추가하여 문제가 해결되는지 확인할 수 있습니다.저는 아마 더 높은 수준의 라우팅, 아마도 더 높은 수준에서 이것을 고칠 수 있는 방법이 있는지와 같은 인라인 방식을 피할 것입니다.

저는 도움이 될 만한 실패 테스트를 작성했습니다.

$.post($frm.attr("action"), ko.mapping.toJSON(data, map))
.done(function (dataVal) {
    //process dataVal
    var mystruct = GenerateCache($.parseJSON(dataVal));
})
.fail(function (jqxhr, textStatus, error) {
    if (jqxhr.responseText.indexOf("YourMoniker") != -1) {
        parseData($.parseJSON(jqxhr.responseText));
    } else {
        var err = textStatus + ', ' + error;
        console.log("Request Failed: " + err);
    }
});


function GenerateCache(data) {
    var obj = function () { };
    obj.prototype = data;
    return new obj();
}

구체적으로 의 오류 처리를 살펴봅니다..fail부분.

당신의 컨트롤러가 아닙니다. 잘 작동하고 있습니다.필드가되었습니다. 상태 코드 필수필없다니를 합니다. IE와 Chrome 모두 상태 코드를 반환합니다.400 Bad Request하고 있습니다.responseText그리고 너에게 주는 것[{"Name":"Nome","ErrorMessage":"campo obrigatório."}]양식 필드가 누락되었음을 의미합니다.

을 다 처리 도 불구하고 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ IE ㅠㅠㅠㅠㅠㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅠXMLHttpRequest.responseText코드를 가 응답 코드로 . 200과 IE의 두 번째 코드는 다음과 .

Headers (Response)

HTTP/1.1 400 Bad Request
...
Content-Length: 11

Bad Request

이를 처리하는 "콘텐츠"가 적절한 json 응답이 아닌 "불량 요청" 상태 텍스트임을 나타냅니다(예: Chrome에서 콘텐츠 길이 54로 읽음).이것은 IE가 당신의 응답 본문을 버리거나(믿을 수 없을 정도로 믿을 수 없을 정도로) "적절하게" 처리되지 않았다는 것을 의미할 수 있습니다.나머지를 버려보세요.jqXHR 입니다.fail어딘가에서 찾을 수 있는지 확인할 수 있는 핸들러입니다.

IE(IE11을 포함한 모든 버전)는 상태 텍스트에 "Bad Request"를 넣고 메시지로 입력한 JSON을 무시합니다.

xhr.하려면 IE에서 xhr.response를 사용하여 또는 .Text를 사용하려면 다음과 같이 Json 또는 JsonResult를 반환하는 대신 예외를 던져야 합니다.HttpStatusCode.BadRequest;

그래서... 전에:

Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(new { Message = "There is already a distribution set which covers part or all of this period" });

이것은 크롬, FF 그리고 모든 정상적인 브라우저에서 작동합니다.이후:

throw new Exception("You have posted invalid datas.");

처리되지 않은 예외로, 응답으로 브라우저에 전달되며, 이는 Chrome, FF 및 IE에서도 작동합니다.처리되지 않은 모든 예외(또는 해당 사항에 대한 정당한 예외)와 마찬가지로 우아하지는 않지만 적절한 응답을 받을 수 있도록 지원합니다.

언급URL : https://stackoverflow.com/questions/22071211/when-performing-post-via-ajax-bad-request-is-returned-instead-of-the-json-resul

반응형