我有两个http请求,一个用curl编写,一个用javascript用chrome编写。 curl请求有效,但chrome请求没有,但我不确定原因。
铬:
PUT /api/Account HTTP/1.1
Host: mydomain.co.nz
Connection: keep-alive
Content-Length: 152
Pragma: no-cache
Cache-Control: no-cache
Authorization: Bearer eyJhb..
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Content-Type: multipart/form-data; boundary=--------------------------33e4cd665cd7a003
Accept: application/json
Referer: http://localhost:4200/conversations
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
--------------------------33e4cd665cd7a003
Content-Disposition: form-data; name="data"
{"isoncall" : true}
--------------------------33e4cd665cd7a003--
卷曲:
PUT /api/Account HTTP/1.1
Host: mydomain.co.nz
User-Agent: curl/7.51.0
accept: application/json
authorization: Bearer eyJhbGciO....
cache-control: no-cache
Content-Length: 158
Expect: 100-continue
Content-Type: multipart/form-data; boundary=--------------------
----a8c24af99c272f79
--------------------------a8c24af99c272f79
Content-Disposition: form-data; name="data"
{"isoncall" : true}
--------------------------a8c24af99c272f79--
我使用chrome获得的错误是:
[{"错误":" Stream的意外结束,内容可能已被其他组件读取。 ""类型":" IOException的""堆栈":"在Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.d__41.MoveNext()\ r \ n ---从抛出异常的上一个位置的堆栈跟踪结束--- \ r \ n在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(个)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务个)\ r \ n在Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.d__3.MoveNext(个)\ r \ n ---栈跟踪的结尾从先前位置在那里引发异常---在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw \ r \ n(个)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在Microsoft.AspNetCore .WebUtilities.MultipartReader.d__20.MoveNext()\ r \ n ---从抛出异常的上一个位置开始的堆栈跟踪结束--- \ r \ n在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) )\ r \ n在Microsoft.AspNetCore.Http.Features.FormFeature.d__18.MoveNext()\ r \ n ---从抛出异常的上一个位置的堆栈跟踪结束--- \ r \ n在System.Runtime .ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在Microsoft.AspNetCore.Mvc.ModelBinding.FormValueProviderFactory.d__1.MoveNext()\ r \ n ---抛出异常的上一个位置的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n中的\ r \ n )\ r \ n在Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.d__2.MoveNext()\ r \ n ---从抛出异常的上一个位置的堆栈跟踪结束--- \ r \ n在System.Runtime System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotific中的.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n Microsoft.AspNetCore.Mvc.Internal.DefaultControllerArgumentBinder.d__6.MoveNext()\ r \ n中的ation(任务任务)\ r \ n \ n ---从抛出异常的上一个位置开始的堆栈跟踪结束--- \ r \ n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__22.MoveNext() \ r \ n ---从抛出异常的上一个位置开始的堆栈跟踪结束--- \ r \ n在Microsoft.AspNetCore.Mvc.Internal的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n中。 ControllerActionInvoker.Rethrow(ResourceExecutedContext context)\ r \ n在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State&接下来,范围&范围,对象& state,Boolean& isCompleted)\ r \ n在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__20.MoveNext()\ r \ n ---从抛出异常的上一个位置的堆栈跟踪结束--- \ r \ n在System。 Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(个)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务个)\ r \ n在Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext(个)\ r \正 - 抛出异常的上一个位置的堆栈跟踪结束---在System.Runtime.ExilerServices.ExceptionDispatchInfo.Throw()\ r \ n中的系统.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中的\ r \ n \ r \ n在Microsoft.AspNetCore.Builder.Extensions.MapMiddleware.d__3.MoveNext()\ r \ n ---从抛出异常的上一个位置的堆栈跟踪结束--- \ r \ n在System.Runtime。 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotificat中的ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n离子(任务任务)\ r \ n在IdentityModel.AspNetCore.ScopeValidation.ScopeValidationMiddleware.d__3.MoveNext()\ r \ n ---从抛出异常的上一个位置的堆栈跟踪结束--- \ r \ n在系统.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在Microsoft.AspNetCore.Authentication.AuthenticationMiddleware
1.<Invoke>d__18.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware
1.d__18.MoveNext ()\ r \ n ---从抛出异常的先前位置开始的堆栈跟踪结束---在System.Runtime.CompilerServices上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n中的\ r \ n。 IdentityAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationMiddleware.d__7.MoveNext()\ r \ n ---从上一个引发异常的位置的堆栈跟踪结束--- \ r \ n在系统System.Runtime.CompilerSe上的.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n在Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.d__7.MoveNext()\ r \ n中的rvices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n ---从抛出异常的上一个位置开始的堆栈跟踪结束--- \ r \ n在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(个)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务个)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.GetResult() \ r \ n在Celo.Api.Middleware.Exceptions.ExceptionHandlingMiddleware.d__5.MoveNext()在D:\ a \ 1 \ s \ src \ Celo.Api \ Middleware \ Exceptions \ ExceptionHandlingMiddleware.cs:第41行&#34;} ]
我不确定这是怎么失败的。
作为参考,curl命令是:
curl -X PUT https://mydomain.co.nz/api/Account -H 'accept: application/json' -H 'authorization: Bearer eyJhb..' -H 'cache-control: no-cache' -F 'data={"isoncall" : true}'
和javascript调用是:
let xhr:XMLHttpRequest = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log('200', xhr.response)
//resolve(<MyEntity>JSON.parse(xhr.response));
} else {
console.log('err', xhr.response)
//reject(xhr.response);
}
}
};
xhr.open('PUT', 'https://mydomain.co.nz/api/Account', true);
xhr.setRequestHeader("Accept", "application/json")
xhr.setRequestHeader("Authorization", this.authService.getAuth())
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=--------------------------33e4cd665cd7a003')
xhr.send(`--------------------------33e4cd665cd7a003
Content-Disposition: form-data; name="data"
{"isoncall" : true}
--------------------------33e4cd665cd7a003--`)
答案 0 :(得分:1)
这两个请求之间的明显区别在于,在您的XHR请求中,您不必在请求正文中使用两个破折号作为边界的前缀。
如果查看CURL生成的请求,您将看到两个边界有两个额外的破折号(与标题中的边界相比),以及两个额外的破折号后缀为身体的最后一个边界。你的javascript代码中没有前缀。
现在,话虽如此,我可以提出两种可能的解决方案:
修复您当前的代码 - 这可能是一个快速修复。
如上所述,您需要将附加 - 前缀添加到正文中的边界。 其次,我会避免使用多行字符串,并使用\ n作为行分隔符 这将导致以下javascript:
xhr.open('PUT', 'https://mydomain.co.nz/api/Account', true);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Authorization", this.authService.getAuth());
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=--------------------------33e4cd665cd7a003')
xhr.send(`----------------------------33e4cd665cd7a003\n' +
'Content-Disposition: form-data; name="data"\n\n' +
'{"isoncall" : true}\n\n' +
'----------------------------33e4cd665cd7a003--');
您也可以切换到XHR FormData API并避免手动处理所有这些内容。
var formData = new FormData();
formData.append("data", '{"isoncall" : true}');
xhr.open('PUT', 'https://mydomain.co.nz/api/Account', true);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Authorization", this.authService.getAuth());
xhr.send(formData);