我正在尝试安装托管的Windows服务托管的WCF服务,该服务可以为我的网页提供有关安装它的计算机的一些信息。我的想法是,我页面的所有访问者都将安装此服务,页面可以使用javascript调用localhost服务来获取数据。
我们的一位开发人员通过为服务启用CORS来实现这一点
CarlosFigueira's example here。除了在Edge中,它在所有浏览器中都很好用,它会出现错误SCRIPT7002: XMLHttpRequest: Network Error 0x2efd
。我想不出任何理由,也找不到任何关于它的信息,所以我想也许我应该尝试一种jsonp方法。
我认为jsonp应该绕过同源策略,但我只能通过上面提供的支持CORS的WCF服务来实现它。只要我删除它并只使用常规ServiceHost
,我就会开始收到400条错误的请求响应。
**“工作”是指浏览器成功发出请求并收到响应。但是,响应是普通的json,而不是jsonp。我读到WCF 4.5应该自动识别“回调”参数并将json包装在“P”中,但这似乎并没有发生。我认为这是一个无关的次要问题。
但主要的问题是,我认为jsonp应该是一种提出跨域请求的方式,那么为什么我必须在我的WCF服务上启用所有CORS头文件以使其工作?
Windows Service 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 Call:
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) {
}
});
答案 0 :(得分:0)
我从头开始自我托管的虚拟服务,并将问题缩小到我的配置。它需要使用webHttpBinding
作为REST服务,我想,没有明确指定,它使用的是basicHttpBinding
。我删除了标准端点并自己配置了端点:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpBinding" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<services>
<service name="LessonPlansAuthentication.MachineDataService">
<endpoint address="" binding="webHttpBinding"
bindingConfiguration="webHttpBinding"
behaviorConfiguration="webHttpBehavior"
contract="LessonPlansAuthentication.IMachineDataService"/>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
</system.serviceModel>
如果我在进行此更改之前尝试访问浏览器中的URL,则只会显示一个空白页面。之后,它实际上返回JSON数据,jQuery可以成功地对URL进行JSONP AJAX调用。
我还不清楚使用webHttp绑定&amp;端点以及crossDomainScriptAccessEnabled=true
实际上已更改以允许呼叫。响应的内容类型可能?对此有任何意见将不胜感激。
现在我只需验证它适用于所有浏览器。如果有人知道为什么Edge不支持启用CORS的服务,请发表评论。