我試圖安裝託管的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) {
}
});