C# 如何为 WCF 服务添加跨域支持
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14047754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add cross domain support to WCF service
提问by mike_hornbeck
I'm trying to allow POST requests from my javascript app hosted at localhost:80 to a WCF REStful service hosted at a different port, but somehow it doesn't work. I've tried adding custom properties to the header, as well as adding it programatically in my service's JSONData
method but I'm still getting '405 Method not allowed' in my response. What is the proper approach here ?
我试图允许从我的 localhost:80 托管的 javascript 应用程序向托管在不同端口的 WCF RESTful 服务发出 POST 请求,但不知何故它不起作用。我已经尝试向标头添加自定义属性,以及在我的服务JSONData
方法中以编程方式添加它,但我的响应中仍然出现“405 Method not allowed”。这里的正确方法是什么?
This is my interface :
这是我的界面:
namespace RestService
{
public class RestServiceImpl : IRestServiceImpl
{
#region IRestServiceImpl Members
public string JSONData()
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
return "Your POST request";
}
#endregion
}
}
and the service code :
和服务代码:
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Web.Script.Services;
namespace RestService
{
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[ScriptMethod]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "export")]
string JSONData();
}
}
And finally the config :
最后是配置:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
<endpoint address ="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
采纳答案by Akira Yamamoto
This worked better for me than the Web.config version:
这比 Web.config 版本更适合我:
Create a Global.asax
创建一个 Global.asax
Add this method to the Global.asax.cs
:
将此方法添加到Global.asax.cs
:
using System.Web;
namespace StackOverflow
{
public class Global : System.Web.HttpApplication
{
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
}
}
参考:http: //www.dotnet-tricks.com/Tutorial/wcf/X8QN260412-Calling-Cross-Domain-WCF-Service-using-Jquery.html
回答by carlosfigueira
Enabling CORS for non-GET requests requires more than just setting the Access-Control-Allow-Origin
header - it also needs to deal with preflightrequests, which are OPTIONS
requests which ask the server whether it's safe to perform operations which can potentially change data (e.g., POST, PUT, DELETE) before the actual request is sent.
为非 GET 请求启用 CORS 不仅需要设置Access-Control-Allow-Origin
标头 - 它还需要处理预检请求,这些OPTIONS
请求询问服务器执行可能更改数据的操作是否安全(例如,POST、PUT、DELETE ) 在发送实际请求之前。
I've written a blog post about adding CORS support for WCF. It's not the simplest of the implementations, but hopefully the code in the post can be simply copied / pasted into your project. The post can be found at http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx.
我写了一篇关于为 WCF 添加 CORS 支持的博客文章。这不是最简单的实现,但希望帖子中的代码可以简单地复制/粘贴到您的项目中。该帖子可以在http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx上找到。
回答by Akira Yamamoto
Add these nodes to your Web.config:
将这些节点添加到您的 Web.config:
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
<add name="Access-Control-Max-Age" value="1728000" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
参考:http: //theagilecoder.wordpress.com/2014/07/07/wcf-and-cors-no-access-control-allow-origin-header-is-present-on-the-requested-resource/
回答by QA Collective
The following .NET code (global.asax) has an important difference that in stead of *, it can be better to echo back the Origin domain because this enables authentication over CORS (e.g. NTLM / Kerberos) as well as the Preflight.
以下 .NET 代码 (global.asax) 有一个重要区别,它不是 *,而是回显 Origin 域更好,因为这可以通过 CORS(例如 NTLM / Kerberos)和预检进行身份验证。
void Application_BeginRequest(object sender, EventArgs e)
{
if (Request.HttpMethod == "OPTIONS")
{
Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
Response.AddHeader("Access-Control-Max-Age", "1728000");
Response.End();
}
else
{
Response.AddHeader("Access-Control-Allow-Credentials", "true");
if (Request.Headers["Origin"] != null)
Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]);
else
Response.AddHeader("Access-Control-Allow-Origin" , "*");
}
}