【发布时间】:2019-06-03 15:56:49
【问题描述】:
我的朋友(真实的故事,不是假的)正在尝试使用 Angular 服务中使用的 XMLHttpRequest 发出发布请求。 他试图到达一个有效的 WCF 端点,当从 ASP.NET 应用程序(或邮递员)接近它时它正在工作。 问题是有时他得到请求 readyState = 4 但请求状态 = 0。第二次尝试再次执行此操作(请参阅下面代码中的“if-else”案例)- 以成功(??????)
我假设这与 WCF 配置有关(CORS 选项应该在服务器 web.config 文件中注意 - 参见下文),或者与 post header 选项有关。 这是角度服务代码:
import {Injectable, OnInit} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class BaseServiceService implements OnInit {
constructor( private _http: HttpClient) { }
public authenticate(user, callback)
{
const xmlreq = new XMLHttpRequest();
xmlreq.open('POST', '<WCF service>.svc', true);
xmlreq.setRequestHeader('Content-Type', 'text/xml;charset=utf-8');
xmlreq.responseType = 'document';
const message = '<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">\n' +
'<s:Body>' +
'<Authenticate xmlns="http://tempuri.org/">' +
<some xml data used in the post request as body> +
'</Authenticate>' +
'</s:Body>' +
'</s:Envelope>';
xmlreq.setRequestHeader('SOAPAction',
'http://tempuri.org/IAdministrationService/Authenticate');
xmlreq.onreadystatechange = function () {
if (xmlreq.readyState === 4 && xmlreq.status === 200 )
{
callback.apply(this, [xmlreq.responseXML]);
}
else //try it again and it will work
{
xmlreq.open('POST', '<WCF service>.svc', true);
xmlreq.setRequestHeader('Content-Type', 'text/xml;charset=utf-8');
xmlreq.responseType = 'document';
const message = '<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">\n' +
'<s:Body>' +
'<Authenticate xmlns="http://tempuri.org/">' +
<some xml data used in the post request as body> +
'</Authenticate>' +
'</s:Body>' +
'</s:Envelope>';
xmlreq.setRequestHeader('SOAPAction',
'http://tempuri.org/IAdministrationService/Authenticate');
xmlreq.onreadystatechange = function ()
{
if (xmlreq.readyState === 4 && xmlreq.status === 200 )
{
callback.apply(this, [xmlreq.responseXML]);
}
}
xmlreq.send(message);
}
};
xmlreq.send(message);
}
}
这是服务器 web.config 文件:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation targetFramework="4.0"/>
<pages controlRenderingCompatibilityVersion="4.0"/>
</system.web>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="MyCostumBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!-- this part was added to allow large messages -->
<bindings>
<basicHttpBinding>
<binding name="MyServiceBinding"
hostNameComparisonMode="StrongWildcard"
receiveTimeout="01:30:00"
sendTimeout="00:30:00"
openTimeout="00:30:00"
closeTimeout="00:30:00"
maxReceivedMessageSize="996553600"
maxBufferSize="96553600"
maxBufferPoolSize="9524288"
transferMode="Buffered"
messageEncoding="Text"
textEncoding="utf-8"
bypassProxyOnLocal="false"
useDefaultWebProxy="true" >
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="false"/>
</system.serviceModel>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Logs\Prod\Mediator.svclog"/>
</listeners>
</source>
</sources>
</system.diagnostics>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Content-Security-Policy" value="connect-src http://*"/>
<add name="Access-Control-Allow-Origin" value="http://localhost:4200"/>
<add name="Access-Control-Allow-Headers" value="Origin, SOAPACTION, x-requested-with, content-type,X-Auth-Token,Accept" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PATCH, PUT, DELETE, OPTIONS" />
<add name="Access-Control-Max-Age" value="3600" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
<connectionStrings>
<clear/>
<add name="Configuration" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source = |DataDirectory|\Configuration.accdb"/>
<add name="Configuration_SQL" connectionString=""/>
<add name="Subscription_SQL" connectionString=""/>
</connectionStrings>
</configuration>
【问题讨论】:
标签: angular wcf xmlhttprequest