我的朋友(真实的故事,不是假的)正在尝试使用角度服务中使用的XMLHttpRequest发出发布请求。 他正在尝试到达一个有效的WCF端点,并从ASP.NET应用程序(或邮递员)接近该端点时可以正常工作。 问题是,有时他会收到请求readyState = 4但请求状态=0。第二次尝试再次执行此操作(请参见下面的代码“ if-else”情况)-结尾为成功(?????)
我假设这与WCF配置(服务器的web.config文件中的CORS选项应已注意-参见下文)或帖子标头选项有关。 这是有角度的服务代码:
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>
答案 0 :(得分:0)
处理CORS请求可能有问题。我建议您可以将带有以下代码段的Global.asax文件添加到项目中。
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.End();
}
}
此外,当我们在Angular项目中使用SOAP Web服务时,请求主体是如此复杂,建议您将Restful Web服务与ASP.net WebAPI结合使用。
随时让我知道问题是否仍然存在。