使用 Cors 问题跨域调用 ServiceStack 服务

Posted

技术标签:

【中文标题】使用 Cors 问题跨域调用 ServiceStack 服务【英文标题】:Calling ServiceStack Service Cross-Domain with Cors Issue 【发布时间】:2013-06-07 05:21:44 【问题描述】:

我正在本地机器上测试一些 Web 服务。因为测试页面位于端口 80 的根目录上,而 Web 服务位于不同的端口上,所以我从 Chrome 的诊断工具中收到以下错误:

XMLHttpRequest cannot load http://PCNAME:8083/PackageSearch. Origin http://PCNAME is not allowed by Access-Control-Allow-Origin.

经过一番搜索,我发现了 ServiceStack 的 CORS 特性,并将以下属性放在我的 Web Service 上:

[EnableCors(allowedMethods: "GET, POST")]

但是,错误仍然存​​在。这是ajax调用:

function packageSearch(tourCode) 
            var searchUrl = url + 'PackageSearch';
            var searchData = 
                TourCode: tourCode,
            ;
            $.ajax(searchUrl,
                    data : JSON.stringify(searchData),
                    type: 'POST',
                    contentType: 'application/json, charset=utf-8',
                    dataType: 'json',
                    success: function (result) 
                       oTable.fnClearTable();
                   );
        ;

urlhttp://PCNAME/

编辑

我什至在配置阶段设置了以下内容:

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

        RequestFilters.Add((httpReq, httpRes, requestDto) =>
            
                if (httpReq.HttpMethod == "OPTIONS")
                    httpRes.End();
            );
        base.SetConfig(new EndpointHostConfig
        
            DefaultContentType = "application/json",
            GlobalResponseHeaders = 
             "Access-Control-Allow-Origin", "*" ,
             "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" ,
             "Access-Control-Allow-Headers", "Content-Type, origin, accept" ,
        
        );
        );
       // Configure

【问题讨论】:

您是否已将 Web 服务部署为控制台应用程序? @BhushanFirake,是的 - 目前它们是独立的自托管的。 那你就不需要cors @BhushanFirake,错误消息提示其他情况。 您在发送数据时没有使用JSON.Stringify(),还是您设置了DefaultContentType 【参考方案1】:

您需要指定 ContentType,并且可能必须执行预检消息 (OPTIONS) 来进行握手,从而允许您继续进行跨域调用。

【讨论】:

另外,我遇​​到了一个非常奇怪的问题,fiddler 拦截了我的一些消息和内容,所以如果你打开它,也尝试关闭它。 我已经添加了内容类型。而且我没有看到任何其他需要预检消息的示例,但有趣的是,一旦我添加了它,我在 access-control-origin 上收到了 2 条错误消息,而不是 1 条。 是的。请参阅编辑。这些标头是为所有服务/请求设置的(至少,这是我的理解)【参考方案2】:

我认为这段代码看起来很可疑:

if (httpReq.HttpMethod == "OPTIONS")
    httpRes.End();

我认为尽管您将所有标头响应设置为发送 CORS 标头,但您可能会短路 HTTP 响应标头 - 它们永远不会被发送。您可以验证您是否使用 Fiddler 检查发回的确切 http 响应标头。

看到这个答案:ServiceStack returns 405 on OPTIONS request 他们在调用 httprequest.end() 之前发送标头。

你可能必须这样做:

httpRes.AddHeader("Access-Control-Allow-Origin", "*");

... 在调用 response.end() 之前

【讨论】:

以上是关于使用 Cors 问题跨域调用 ServiceStack 服务的主要内容,如果未能解决你的问题,请参考以下文章

Angular 或 Angular 6 中的跨域资源共享 (CORS)。在 localhost 上使用不同端口进行跨域调用时出现问题

跨域CORS原理及调用具体示例

zuul+security跨域Cors问题解决

zuul+security跨域Cors问题解决

使用微软CORS包不能跨域访问的问题

AJAX跨域调用相关知识-CORS和JSONP