programing

ASP에서 HTTP OPTIONS 동사를 지원하는 방법.NET MVC/WebAPI 응용 프로그램

starjava 2023. 3. 3. 16:47
반응형

ASP에서 HTTP OPTIONS 동사를 지원하는 방법.NET MVC/WebAPI 응용 프로그램

ASP를 설정했습니다.MVC 4/Web API 템플릿으로 시작하는 NET 웹 애플리케이션.일이 잘 풀리는 것 같아요. 제가 아는 바로는 문제가 없어요.Chrome과 Firefox를 사용하여 사이트를 살펴보았습니다.Fiddler를 사용해 테스트해 봤는데, 모든 답변이 돈이 되는 것 같습니다.

이 새로운 웹 API를 사용하기 위해 간단한 Test.aspx를 작성하겠습니다.스크립트의 관련 부분:

<script type="text/javascript">
    $(function () {

        $.ajax({
            url: "http://mywebapidomain.com/api/user",
            type: "GET",
            contentType: "json",
            success: function (data) {

                $.each(data, function (index, item) {

                    ....

                    });
                }
                );

            },
            failure: function (result) {
                alert(result.d);
            },

            error: function (XMLHttpRequest, textStatus, errorThrown) {
                alert("An error occurred, please try again. " + textStatus);
            }

        });

    });
</script>

그러면 REQUEST 헤더가 생성됩니다.

OPTIONS http://host.mywebapidomain.com/api/user HTTP/1.1
Host: host.mywebapidomain.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://mywebapidomain.com
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive

현재 상태로 Web API는 405 Method Not Allowed를 반환합니다.

HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 30 Sep 2013 13:28:12 GMT
Content-Length: 96

<Error><Message>The requested resource does not support http method 'OPTIONS'.</Message></Error>

OPTIONS 동사는 기본적으로 Web API 컨트롤러에 연결되어 있지 않은 것으로 알고 있습니다.그래서 UserController.cs에 다음 코드를 넣었습니다.

// OPTIONS HTTP-verb handler
public HttpResponseMessage OptionsUser()
{
    var response = new HttpResponseMessage();
    response.StatusCode = HttpStatusCode.OK;
    return response;
}

...이것으로 405 Method Not Allowed 에러는 삭제되었지만 응답은 완전히 비어 있습니다.데이터는 반환되지 않습니다.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 30 Sep 2013 12:56:21 GMT
Content-Length: 0

분명 다른 논리가 있을 거야...Options 메서드를 올바르게 코드화하는 방법이나 컨트롤러가 코드를 넣는 올바른 위치인지도 모르겠습니다.웹 API 사이트가 Firefox 또는 Chrome에서 볼 때 올바르게 반응하는 것은 이상하지만 위의 .ajax 호출에 오류가 발생합니다..ajax 코드의 "비행 전" 체크는 어떻게 처리합니까?클라이언트 측의 .ajax 논리로 이 문제를 해결해야 할 것 같습니다.OPTIONS 동사를 처리하지 않아 서버 측에서 문제가 발생한 경우.

누구 도와줄 사람?이것은 매우 일반적인 문제임에 틀림없고, 만약 여기에서 해결이 되었다면 사과드립니다.검색해 봤지만 도움이 되는 답을 찾지 못했어요.

IMHO 업데이트. 이것은 클라이언트 측 문제이며 위의 Ajax JQuery 코드와 관련이 있습니다.웹 브라우저에서 mywebapidomain/api/user에 접속해도 Fiddler가 405 에러 헤더를 표시하지 않기 때문에 이렇게 말합니다.이 문제를 재현할 수 있는 유일한 장소는 JQuery .ajax() 호출입니다.또, 상기의 같은 Ajax 콜은, 서버(동일한 도메인)로 동작하고 있는 경우, 정상적으로 동작합니다.

다른 게시물을 찾았습니다.AJAX 시제품 요청은 GET이 아닌 OPTIONS로 전송되었습니다.관련된 것으로 보이는 501개의 오류가 발생했지만, 저는 그들의 제안을 수정했지만 성공하지 못했습니다.분명히 JQuery는 Ajax 요구가 크로스 도메인(내 요구)일 경우 OPTIONS 헤더를 트리거하는 헤더를 몇 개 추가하도록 코드화되어 있습니다.

'X-Requested-With': 'XMLHttpRequest',
'X-Prototype-Version': Prototype.Version,

JQuery의 핵심 코드를 수정하는 것보다 더 나은 솔루션이 있을 것 같습니다.

다음 답변에서는 이것이 서버측 문제라고 가정하고 있습니다.그럴지도 모르죠, 하지만 전 고객 쪽으로 기울어져서 호스팅 제공업체에 전화하는 건 도움이 안 돼요.

Mike Goodwin의 답변은 훌륭하지만, 제가 시도해보니 MVC5/WebApi 2.1을 겨냥한 것 같았습니다.Microsoft 의 의존 관계.AspNet.WebApi.내 MVC4 프로젝트는 코르스가 잘 안됐어

MVC4를 사용하여 WebApi에서 CORS를 활성화하는 가장 간단한 방법은 다음과 같습니다.

모든 것을 허용했습니다.Origins는 API가 서비스하기를 원하는 클라이언트로 한정할 것을 권장합니다.모든 것을 허용하는 것은 보안상의 위험입니다.

Web.config:

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD" />
        <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
      </customHeaders>
    </httpProtocol>
</system.webServer>

BaseApiController.cs:

OPTIONS http 동사를 허용하기 위해 이 작업을 수행합니다.

 public class BaseApiController : ApiController
  {
    public HttpResponseMessage Options()
    {
      return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
    }
  }

다니엘 A로.White는 코멘트에서 OPTIONS 요청은 크로스 도메인 JavaScript 요청의 일부로 클라이언트에 의해 작성될 가능성이 높다고 말했습니다.이 작업은 Cross Origin Resource Sharing(CORS; 오리진 자원 공유) 준거 브라우저를 통해 자동으로 수행됩니다.이 요구는 예비 요구 또는 프리플라이트 요구입니다.실제 AJAX 요구 전에 실시되어 어떤 요구 동사와 헤더가 CORS에서 지원되는지 판단합니다.서버는 HTTP 동사의 전부 또는 일부에 대해 지원하지 않도록 선택할 수 있습니다.

그림을 완성하기 위해 AJAX 요청에는 JavaScript를 호스팅하는 원본 페이지가 어디서 제공되었는지를 식별하는 추가 "Origin" 헤더가 있습니다.서버는, 임의의 송신원으로부터의 요구를 서포트하도록 선택할 수도 있고, 기존의 신뢰할 수 있는 송신원 세트만을 서포트하도록 선택할 수도 있습니다.임의의 송신원을 허가하는 것은, 사이트간 요구 위조(CSRF)의 리스크를 높일 수 있기 때문에, 시큐러티상의 리스크가 됩니다.

따라서 CORS를 활성화해야 합니다.

ASP에서 이 작업을 수행하는 방법을 설명하는 링크가 있습니다.넷 웹 API

http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#enable-cors

여기에 설명된 구현에서는 특히 다음을 지정할 수 있습니다.

  • 액션 단위, 컨트롤러 단위 또는 글로벌 단위로 CORS 지원
  • 지원되는 원본
  • 컨트롤러 또는 글로벌레벨의 CORS를 이노블로 하면 지원되는HTTP 동사
  • 서버가 교차 원본 요청과 함께 인증 정보 전송을 지원하는지 여부

일반적으로 이것은 정상적으로 동작하지만, 특히 임의의 도메인으로부터의 크로스 오리진 요구를 허가하는 경우는, 시큐러티상의 리스크를 인식할 필요가 있습니다.이것을 허락하기 전에 신중히 생각하라.

어떤 브라우저가 CORS를 지원하는지 Wikipedia에서는 다음과 같은 엔진이 CORS를 지원한다고 합니다.

  • Gecko 1.9.1 (FireFox 3.5)
  • WebKit (Safari 4, Chrome 3)
  • MSHTML/Trident 6(IE10) (IE8 및 9에서 부분 지원)
  • Presto (Opera 12)

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing#Browser_support

여기에 추가해 주세요.Application_OnBeginRequestmethod(이것에 의해, 애플리케이션의 CORS 서포트가 글로벌하게 유효하게 됩니다)와 「비행 전 요구를 처리」합니다.

var res = HttpContext.Current.Response;
var req = HttpContext.Current.Request;
res.AppendHeader("Access-Control-Allow-Origin", req.Headers["Origin"]);
res.AppendHeader("Access-Control-Allow-Credentials", "true");
res.AppendHeader("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
res.AppendHeader("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");

// ==== Respond to the OPTIONS verb =====
if (req.HttpMethod == "OPTIONS")
{
    res.StatusCode = 200;
    res.End();
}

* 보안: 이렇게 하면 어디에서나 서버에 대한 Ajax 요청이 활성화된다는 점에 유의하십시오(원하는 경우 쉼표로 구분된 오리진/url 목록만 허용됩니다).

현재 클라이언트 오리진을 대신 사용했습니다.*이렇게 하면 자격 증명 => 설정이 허용되기 때문입니다.Access-Control-Allow-Credentialstrue는 크로스 브라우저 세션 관리를 가능하게 합니다.

또한 삭제 및 풋, 패치 및 옵션 동사를 활성화해야 합니다.webconfig부분system.webServer그렇지 않으면 IIS에 의해 차단됩니다.

<handlers>
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

이것이 도움이 되기를 바란다

Web API 2 프로젝트에서 같은 문제가 발생한 후(또한 여기서 설명할 가치가 없는 이유로 표준 CORS 패키지를 사용할 수 없게 된 후) 커스텀 Delagating Handler를 구현하여 이 문제를 해결할 수 있었습니다.

public class AllowOptionsHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var response = await base.SendAsync(request, cancellationToken);

        if (request.Method == HttpMethod.Options &&
            response.StatusCode == HttpStatusCode.MethodNotAllowed)
        {
            response = new HttpResponseMessage(HttpStatusCode.OK);
        }

        return response;
    }
}

Web API 설정의 경우:

config.MessageHandlers.Add(new AllowOptionsHandler());

Web.config 에서는 CORS 헤더가 유효하게 되어 있는 것에 주의해 주세요.여기에 게재되어 있는 다른 답변과 같습니다.

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <remove name="WebDAVModule" />
  </modules>

  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="accept, cache-control, content-type, authorization" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>

  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="TRACEVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>

제 프로젝트에는 MVC가 포함되지 않고 Web API 2만 포함되어 있습니다.

global.asax의 커스텀 코드만으로 비행 전 Ajax 옵션 요청에서 발생한 405 및 404 오류를 극복할 수 있었습니다.

protected void Application_BeginRequest()
    {            
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            //These headers are handling the "pre-flight" OPTIONS call sent by the browser
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
            HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
            HttpContext.Current.Response.End();
        }
    }

PS: 모든 것을 허용할 때는 보안상의 문제를 고려하십시오.*

"Access-Control-Allow-Origin" 헤더에 여러 값이 포함되어 있기 때문에 CORS를 비활성화해야 했습니다.

web.config에서도 이 작업이 필요:

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
  <remove name="OPTIONSVerbHandler"/>
  <remove name="TRACEVerbHandler"/>
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>

또한 app.pool을 통합 모드로 설정해야 합니다.

저도 같은 문제가 있었어요.수정은 jQuery AJAX 호출에서 사용자 지정 콘텐츠 유형을 삭제하는 것이었습니다.커스텀 콘텐츠유형은 프리플라이트 요청을 트리거합니다.이걸 찾았어요

다음 조건에 해당하는 경우 브라우저는 비행 전 요청을 건너뛸 수 있습니다.

은 " " " 입니다.GET,HEAD , 「」POST,

프로그램에서는 " " " " 이외의 .Accept,Accept-Language,Content-Language,Content-Type , 「」Last-Event-ID,

Content-Type설정되어 경우는 다음 중

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

이 페이지부터 : http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api ('Preflight Requests' 아래)

ASP.NET web api 2 에서는, CORS 서포트가 추가되었습니다.[ http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api ]링크를 확인해 주세요.

    protected void Application_EndRequest()
    {
        if (Context.Response.StatusCode == 405 && Context.Request.HttpMethod == "OPTIONS" )
        {
            Response.Clear();
            Response.StatusCode = 200;
            Response.End();
        }
    }

저도 같은 문제에 직면했어요.

브라우저의 (CORS) 컴플라이언스 문제를 해결하려면 다음 단계를 따릅니다.

Cors 레퍼런스를 사용하여 REDRock을 솔루션에 포함시키십시오.Web API 솔루션에 대한 Web ActivatorEx 참조를 포함합니다.

그런 다음 Web API App_Start 폴더에 CorsConfig 파일을 추가합니다.

[assembly: PreApplicationStartMethod(typeof(WebApiNamespace.CorsConfig), "PreStart")]

namespace WebApiNamespace
{
    public static class CorsConfig
    {
        public static void PreStart()
        {
            GlobalConfiguration.Configuration.MessageHandlers.Add(new RedRocket.WebApi.Cors.CorsHandler());
        }
    }
}

이러한 변경으로 모든 브라우저에서 webapi에 액세스할 수 있게 되었습니다.

저도 같은 문제가 있었는데, 이렇게 해결했습니다.

web.config에 입력하기만 하면 됩니다.

<system.webServer>
    <modules>
      <remove name="WebDAVModule" />
    </modules>

    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Expose-Headers " value="WWW-Authenticate"/>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, PATCH, DELETE" />
        <add name="Access-Control-Allow-Headers" value="accept, authorization, Content-Type" />
        <remove name="X-Powered-By" />
      </customHeaders>
    </httpProtocol>

    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
</system.webServer>
//In the Application_OnBeginRequest method in GLOBAL.ASX add the following:-  

var res = HttpContext.Current.Response;  
var req = HttpContext.Current.Request;  
res.AppendHeader("Access-Control-Allow-Origin", "*");  
res.AppendHeader("Access-Control-Allow-Credentials", "true");  
res.AppendHeader("Access-Control-Allow-Headers", "Authorization");  
res.AppendHeader("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");  

    // ==== Respond to the OPTIONS verb =====
    if (req.HttpMethod == "OPTIONS")
    {
        res.StatusCode = 200;
        res.End();
    }

//Remove any entries in the custom headers as this will throw an error that there's to  
//many values in the header.  

<httpProtocol>
    <customHeaders>
    </customHeaders>
</httpProtocol>

언급URL : https://stackoverflow.com/questions/19095777/how-to-support-http-options-verb-in-asp-net-mvc-webapi-application

반응형