3

ServiceStack を使用して REST Web サービスを構築しています。クロスドメイン リクエストを許可したいので、CorsFeature プラグインを登録しました。

私の AppHost は次のようになります。

public class HomeAppHost : AppHostHttpListenerBase 
{
    public Context Context { get; set; }

    public HomeAppHost(Context context)
        : base("HomeAutomation", typeof(HomeInterfaceService).Assembly)
    {
        Context = context;
    }

    public override void Configure(Funq.Container container)
    {
        Plugins.Add(new CorsFeature());

        Routes
            .Add<HomeInterface>("/HomeInterface")
            .Add<HomeInterface>("/HomeInterface/{Id}")
            .Add<ViewModel>("/ViewModel")
            .Add<FunctionInput>("/Function")
        ;
    }
}

次に、サービスに対して OPTIONS 要求が行われると、405 Method Not Allowed という結果になります。

リクエスト:

OPTIONS /Function HTTP/1.1
Host: localhost:1337
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0 FirePHP/0.7.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: nl,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Origin: http://localhost
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
x-insight: activate
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

応答:

HTTP/1.1 405 Method Not Allowed
Content-Length: 1837
Content-Type: application/xml
Server: Microsoft-HTTPAPI/2.0
Date: Fri, 15 Feb 2013 20:19:33 GMT

編集


空の Options メソッドをサービスに追加すると、実際に 405 がトリガーされなくなります。ただし、応答は空のようです。

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Server: Microsoft-HTTPAPI/2.0
Date: Sat, 16 Feb 2013 08:44:21 GMT

以下を追加しても、空の応答が得られます。

RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
    //Handles Request and closes Responses after emitting global HTTP Headers
    if (httpReq.HttpMethod == "OPTIONS")
        httpRes.End();
});

httpReq.Method を httpReq.HttpMethod に、httpRes.EndServiceStackRequest() を httpRes.End() に変更する必要がありました。これは正しいです?

4

3 に答える 3

2

私はこの行動に少し戸惑いました。すべてのサービスでダミーの Options() メソッドを作成したり、すべての Dto クラスに偽のルートを追加したりしたくありませんでした。私が必要としていたのは、ServiceStack AppHost がすべての「OPTIONS」リクエストに対して、すべての URL で同じ動作で応答したことだけです。これで私は終わりました。

オプション用に独自のハンドラーを作成しました。

public class OptionsRequestHandler : IHttpHandler, IServiceStackHttpHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        ProcessRequest(null, new HttpResponseWrapper(context.Response), null);          
    }

    public void ProcessRequest(IHttpRequest httpReq, IHttpResponse httpRes, string operationName)
    {
        httpRes.EndServiceStackRequest();
        return;
    }
}

次に、ホストの Configure メソッドに追加しました。

this.CatchAllHandlers.Add((httpMethod, pathInfo, filePath) =>
{
    if ("OPTIONS".Equals(httpMethod, System.StringComparison.InvariantCultureIgnoreCase))
        return new OptionsRequestHandler();
    else return null;
});

CorsFeature も忘れていませんでした:

host.Plugins.Add(new ServiceStack.ServiceInterface.Cors.CorsFeature());

したがって、このように ServiceStack は、URL、dto、およびサービスの宣言に関係なく、「OPTIONS」ヘッダーを含むすべてのリクエストに対して「200 OK」で応答します。

于 2013-04-30T10:50:06.857 に答える
2

これが正しい方法かどうかはわかりませんが、現在、リクエスト フィルターを使用して CORS を自分で処理しています。

RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
    httpRes.AddHeader("Access-Control-Allow-Origin", "*");

    if (httpReq.HttpMethod == "OPTIONS")
    {
        httpRes.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        httpRes.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
        httpRes.End();
    }
});
于 2013-02-16T10:11:07.690 に答える
2

ServiceStackの405は、メソッドが実装されていないことを意味します。

Optionsそのため、動詞のハンドラーを追加する必要があります。メソッド本体は空にすることができます。例:

public MyService : Service 
{ 
    public void Options(HomeInterface request) {}
}

すべてのOptions リクエストを (つまり、どのサービスであるかに関係なく)許可したい場合は、次のようなグローバル リクエスト フィルターを登録できます。

this.RequestFilters.Add((httpReq, httpRes, requestDto) => {
   //Handles Request and closes Responses after emitting global HTTP Headers
    if (httpReq.Method == "OPTIONS") 
        httpRes.EndServiceStackRequest();
});

Option リクエストの処理方法をより細かく制御したい場合は、 Filter Attributesで同じロジックを使用できます。

于 2013-02-15T21:35:54.420 に答える