我试图安装托管的Windows服务托管的WCF服务,它可以为我的网页提供关于它所安装的机器的一些信息。这个想法是,我的页面的所有访问者将安装此服务,并且页面可以使用javascript调用localhost服务以获取其后的数据。允许浏览器从Windows服务托管的WCF服务请求JSONP
我们的开发人员之一通过使用 CarlosFigueira's example here启用CORS服务将这一切放在一起。它在除了Edge以外的所有浏览器都很好用,它给出了错误SCRIPT7002: XMLHttpRequest: Network Error 0x2efd
。我想不出任何理由,也无法找到任何信息,所以我想也许我应该尝试一种jsonp方法。
我以为jsonp应该绕过同源策略,但我只能使它工作**与上述启用CORS的WCF服务的东西仍然在原地。只要我删除它,只是使用一个普通的ServiceHost
,我开始得到一个400 - 错误的请求响应。
**“工作”是指浏览器成功发出请求并收到响应。但是,响应是普通的json,而不是jsonp。我读过WCF 4.5应该自动识别“callback”参数并将json包装在“P”中,但似乎并未发生。我认为这是一个无关的次要问题。
但主要问题是,我认为jsonp应该是一种制作跨域请求的方式,为什么我必须启用我的WCF服务上的所有CORS标头才能使其工作?
Windows服务的OnStart:
CorsEnabledServiceHostFactory serviceHostFactory = new CorsEnabledServiceHostFactory();
serviceHost = serviceHostFactory.GetServiceHost(typeof(LPA.MachineDataService), baseAddresses); //Works
//LPA.MachineDataService singleton = new LPA.MachineDataService();
//serviceHost = new System.ServiceModel.ServiceHost(singleton, baseAddresses); //Doesn't work
serviceHost.Open();
的ServiceContract:
[ServiceContract]
public interface IMachineDataService
{
[WebGet(UriTemplate = "GetValues", ResponseFormat=WebMessageFormat.Json)]
LPA.MachineData GetValues();
}
服务实现:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MachineDataService : IMachineDataService
{
public LPA.MachineData GetValues()
{
LPA.MachineData result = null;
try
{
WebOperationContext.Current.OutgoingResponse.Headers[HttpResponseHeader.CacheControl] = "no-cache";
result = PcValues.GetValues();
}
catch (Exception ex)
{
}
return result;
}
}
从Windows服务的app.config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<standardEndpoints>
<webScriptEndpoint>
<standardEndpoint crossDomainScriptAccessEnabled="true" name=""></standardEndpoint>
</webScriptEndpoint>
<webHttpEndpoint>
<standardEndpoint crossDomainScriptAccessEnabled="true" name=""></standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
jQuery的电话:
var valuesAddress = "http://localhost:56731/ValuesService/GetValues";
$.ajax({
type: "GET",
url: valuesAddress,
dataType: "jsonp",
success: function (result) {
$("[data-authinfo]").val(result);
},
error: function (xhr, status, code) {
}
});