两个http请求之间的差异

时间:2017-07-31 01:23:40

标签: ajax http curl request xmlhttprequest

我有两个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获得的错误是:

  

[{&#34;错误&#34;:&#34; Stream的意外结束,内容可能已被其他组件读取。 &#34;&#34;类型&#34;:&#34; IOException的&#34;&#34;堆栈&#34;:&#34;在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&amp;接下来,范围&amp;范围,对象&amp; state,Boolean&amp; 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--`)

1 个答案:

答案 0 :(得分:1)

这两个请求之间的明显区别在于,在您的XHR请求中,您不必在请求正文中使用两个破折号作为边界的前缀。

如果查看CURL生成的请求,您将看到两个边界有两个额外的破折号(与标题中的边界相比),以及两个额外的破折号后缀为身体的最后一个边界。你的javascript代码中没有前缀。

现在,话虽如此,我可以提出两种可能的解决方案:

  1. 修复您当前的代码 - 这可能是一个快速修复。

    如上所述,您需要将附加 - 前缀添加到正文中的边界。 其次,我会避免使用多行字符串,并使用\ 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--');
    
  2. 您也可以切换到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);