4

我正在尝试对 IIS7.5 上托管的 WCF 服务端点进行 CORS 调用。

我在 IIS 中配置了自定义标头。我的配置如下所示

<customHeaders>
            <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
            <add name="Access-Control-Allow-Headers" value="x-user-session,origin, content-type, accept" />
            <add name="Access-Control-Allow-Credentials" value="true" />
        </customHeaders>

当我执行 POST 请求时,我收到以下错误消息“Access-Control-Allow-Headers 不允许请求标头字段 x-user-session”

如果我从调用中删除我的自定义标头并运行它,一切正常。

此外,如果我使用自定义标头进行 GET 调用,那么 API 也可以正常工作。

$.ajax({
   type:"POST",
   success: function(d) { console.log(d) },
   timeout: 9000,
   url: "http://api.myserver.com/Services/v2/CreditCard.svc/update_cc_detail",
   data: JSON.stringify({"card_id":    1234,"expire_month":"11","expire_year":"2020","full_name":"Demo Account", "number":"4111111111111111","is_primary":true}),
   xhrFields: { withCredentials: true}, 
  headers: { x-user-session':  "B23680D0B8CB5AFED9F624271F1DFAE5052085755AEDDEFDA3834EF16115BCDDC6319BD79FDCCB1E199BB6CC4D0C6FBC9F30242A723BA9C0DFB8BCA3F31F4C7302B1A37EE0A20C42E8AFD45FAB85282FCB62C0B4EC62329BD8573FEBAEBC6E8269FFBF57C7D57E6EF880E396F266E7AD841797792619AD3F1C27A5AE" },
crossDomain: true,
   contentType: 'application/json'
});

更新

以下是 FireBug 日志的链接 https://gist.github.com/anonymous/7333130

4

3 回答 3

4

最有可能的问题是OPTIONS请求返回错误(404 或 405)。这可以解释为什么GET正常工作(它并不总是需要预检请求)而POST不能正常工作(它总是需要预检)。

通常,托管在 IIS 上的 WCF 服务最简单的解决方案是通过以下方式启用所有方法WebInvokeAttribute

[WebInvoke(Medthod="*")]
...

有时 IIS 会OPTION使用其默认值阻止请求OPTIONSVerbHandler。您可以通过 web.config 删除此处理程序:

<handlers>
    <remove name="OPTIONSVerbHandler"/>
</handlers>

在最坏的情况下(当OPTIONSIIS 未阻止但 WCF 无法处理时)您可以设置自己的处理程序。在这种情况下,首先您需要一个简单的类,如下面的程序集中的类:

namespace CustomHandlers
{
    public class CORSOPTIONSVerbHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            if (context.Response.HttpMethod == "OPTIONS")
                context.Response.StatusCode = 200;
            else
                context.Response.StatusCode = 405;

            context.Response.End();
        }
    }
}

可以像这样在 web.config 中添加新的处理程序:

<handlers>
    <remove name="OPTIONSVerbHandler"/>
    <add name="CORSOPTIONSVerbHandler" verb="OPTIONS" path="*" type="CustomHandlers.CORSOPTIONSVerbHandler, CustomHandlers"/>
</handlers>

当然你需要适当地调整程序集、命名空间和类名。

于 2013-11-04T15:51:10.287 回答
0

尝试将这些添加到您的 web.config

<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />

它通常是由于跨域请求而发生的

于 2013-11-04T14:17:18.073 回答
0

我有一个类似的问题,但服务堆栈,并且要正确地使您的服务响应 OPTIONS 请求,您需要自己明确地放置标头。也许在 WCF 中没有必要,但我会尝试。

使用 tpeczek 的代码:

namespace CustomHandlers
{
    public class CORSOPTIONSVerbHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            if (context.Response.HttpMethod == "OPTIONS")
                context.Response.StatusCode = 200;
                context.Response.Headers.Add("Access-Control-Allow-Headers" ,"x-user-session,origin, content-type, accept");
            else
                context.Response.StatusCode = 405;

            context.Response.End();
        }
    }
}

我没有尝试过代码,它可能无法运行,但我希望这个想法很清楚:)

于 2013-11-11T13:11:59.500 回答