我在使用JQUERY AJAX消费WCF服务时面临问题。我知道这是跨域问题,已经阅读了很多关于它的解决方案。但没有一个对我有用。以下是所有相关代码。有人可以帮帮我吗?
由于
[OperationContract]
[WebInvoke(Method = "POST",BodyStyle=WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
[return: MessageParameter(Name = "result")]
public ServiceSearchResponse GetSearchResults(ServiceSearchParams sParams)
{
/// search function
}
JQUERY:
$.ajax({
type: 'POST',
url: "http://myserviceurl.com/GetSearchResults",
data: p,
contentType: "application/json; charset=utf-8",
dataType: 'json',
crossDomain: true,
success: function (data) {
alert(data);
},
failure: function (response) {
alert('failed');
},
error: function (response) {
alert(JSON.stringify(response));
}
});
Webconfig:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding" bindingConfiguration="" />
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultServiceBehavior">
<!--Added DefaultServiceBehavior referenced at service tag above-->
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="myserives.services.AppServicesAspNetAjaxBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="mypackage.services.MyServices">
<endpoint address="" behaviorConfiguration="myserives.services.AppServicesAspNetAjaxBehavior" binding="webHttpBinding"
bindingConfiguration="LargeSizeMessages" contract="myContractName" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="LargeSizeMessages" maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647" crossDomainScriptAccessEnabled="true">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
这是它的样子: http://screencast.com/t/b7tsqld6
查看错误: http://screencast.com/t/pWQNAlmMYS3
发布数据中没有任何内容。虽然我发布了数据。
---更新
请参阅我的Global.asax ..我在这里做错了什么:
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();
EnableCrossDmainAjaxCall();
}
private void EnableCrossDmainAjaxCall()
{
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-Credentials",
"true");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers",
"Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age",
"1728000");
HttpContext.Current.Response.End();
}
}
答案 0 :(得分:4)
这是一段工作代码。
<强>接口强>
[ServiceContract]
public interface IDataService
{
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json,BodyStyle=WebMessageBodyStyle.WrappedResponse)]
List<RequestData> GetUser(RequestData data);
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "UsersList/{id}",RequestFormat=WebMessageFormat.Json,BodyStyle=WebMessageBodyStyle.WrappedResponse)]
RequestData UsersList(string id);
}
类实现界面
public class DataService : IDataService
{
public List<RequestData> GetUser(RequestData data)
{
List<RequestData> list = new List<RequestData>();
if (data.Name.ToUpper() == "MAIRAJ")
{
list.Add(new RequestData
{
Name = "Mairaj",
Age = 25,
Address = "Test Address"
});
list.Add(new RequestData
{
Name = "Ahmad",
Age = 25,
Address = "Test Address"
});
}
return list;
}
public RequestData UsersList(string userId)
{
return new RequestData
{
Name = "Mairaj",
Age = 25,
Address = "Test Address"
};
}
}
自定义类
当我将此类的对象作为参数传递给方法并返回此对象时,我正在使用此。你可能不需要它。
[DataContract]
public class RequestData
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
[DataMember]
public string Address { get; set; }
}
<强>的Web.Config 强>
<configuration>
<configSections>
</configSections>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceBehavior" name="WCFWebApp.DataService">
<endpoint address="" binding="webHttpBinding" contract="WCFWebApp.IDataService" behaviorConfiguration="EndpBehavior"/>
</service>
</services>
</system.serviceModel>
</configuration>
这就是你怎么称呼它
var Data = {
Name: "Mairaj",
Age: 20,
Address: "Test Address"
//userId:1
};
$.ajax({
type: "POST",
url: "/DataService.svc/GetUser",
dataType: "JSON",
data: JSON.stringify(Data),
contentType: "application/json; charset=utf-8",
success: function (data) {
alert("Data is " + data);
},
error: function () {
}
});
您需要更改web.config中的服务类名称,并在jquery代码中更改您将调用它的URL。
答案 1 :(得分:0)
我会尝试设置 Access-Control-Allow-Credentials:true i web.config。 还可以尝试将 Access-Control-Allow-Headers 设置为与jquery ajax调用匹配的标头。应该是&#34; application / json&#34;,但请与fiddler(或类似)核实以确定。 最后尝试设置访问控制请求方法:POST
我喜欢类似的问题,在尝试了不同的设置之后我在web.config中找到了一个实际工作的组合。祝你好运:)
<强>更新强>
另外,我会确保access-control-allow-credentials与其他参数的大小写形式相同。即访问控制允许的凭据。我真的没有任何消息来源,但以防万一:)
我会尝试不使用localhost。使用正确的主机名在不同的服务器上设置测试环境。至少Chrome在本地主机上处理cors时遇到问题。
根据http://www.html5rocks.com/en/tutorials/cors/,请求的内容类型应为以下之一:
更新2
你可以尝试更多的东西: 添加:
$.support.cors = true;
之前的
$.ajax({ ...
我认为问题可以通过错误的内容类型来解决。 当我对Sharepoint 2013服务器进行CORS设置时,我添加了这个并且一切正常:
headers: {
"accept": "application/json;odata=verbose;charset=utf-8",
"content-type":"application/json;odata=verbose;charset=utf-8"
},
该内容类型可能与您无关,但我可能很重要的是指定。
答案 2 :(得分:0)
您需要在Access-Control-Allow-Origin
而不是*
中添加请求的域,*
可能无法在所有浏览器中使用,因为它存在安全问题 - 即{}中只允许请求的域{1}}请求,而不是*应在选项响应标头中响应。要解决此问题,您需要将该代码更改为以下内容。
OPTIONS
将HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost");
替换为请求的域名,以编程方式执行此操作,您可以使用此功能 - http://localhost
。
我已在我的博客中更详细地解释了这一点 - Blog,CodeProject