У меня есть два HTTP-запроса, один из которых написан на curl, а другой - на javascript в хроме. Запрос 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--
Ошибка, которую я получаю с хромом:
[{"error": "Неожиданный конец потока, возможно, содержимое уже было прочитано другим компонентом.", "type": "IOException", "stack": "в 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 --- Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) \ r \ n в Microsoft.AspNetCore.WebUtilities.MultipartReader.d \ n --- Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices .ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) \ r \ n в Microsoft.AspNetCore.Http.Features.FormFeature.d__18.MoveNext () \ n-- - Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) \ r \ n в Microsoft.AspNetCore.Mvc.ModelBinding.FormValueProviderFactory.d__1.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices .ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) \ r \ n в Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.d__2.MoveN - Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.Runtime.Ex ceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) \ r \ n в Microsoft.AspNetCore.Mvc.Internal.DefaultController6. - Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в 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 в System.Runtime. ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow (контекст ResourceExecutedContext) \ r \ n в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next (State & Scope, Scope & Scope) Объект и состояние, логическое значение и isCompleted) \ r \ n в Microsoft.AspN etCore.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 \ n --- Конец трассировки стека из предыдущего местоположения где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) \ r \ n в Microsoft.AspNetCore. Builder.Extensions.MapMiddleware.d__3.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) \ r \ n в IdentityMode l.AspNetCore.ScopeValidation.ScopeValidationMiddleware.d__3.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.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 --- End трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) \ r \ n в IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationMiddleware.d__7.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess AndDebuggerNotification (задача задачи) \ r \ n в Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.d__7.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего места, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) \ r \ n в System.Runtime.CompilerServices.TaskResult.Get в Celo.Api.Middleware.Exceptions.ExceptionHandlingMiddleware.d__5.MoveNext () в D: \ a \ 1 \ s \ src \ Celo.Api \ Middleware \ Exceptions \ ExceptionHandlingMiddleware.cs: строка 41 "}]
Я не знаю, почему это не так.
Для справки команда 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 ответ
Явное различие между этими двумя запросами заключается в том, что в вашем запросе 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);
Похожие вопросы
Новые вопросы
ajax
AJAX (асинхронный JavaScript и XML) - это метод создания интерактивных пользовательских интерфейсов веб-сайтов без традиционного обновления или перезагрузки веб-страниц. Он использует асинхронный обмен данными между клиентом и сервером для обновления отображаемой информации и беспрепятственного реагирования на действия пользователя. Включите дополнительные теги для языков программирования, библиотек, фреймворков, веб-браузера, протоколов и другой информации об окружающей среде.
\r\n
вместо новой строки в данных тела--------------------------33e4cd665cd7a003\r\nContent-Disposition: form-data; name="data"\r\n\r\n{"isoncall" : true}\r\n--------------------------33e4cd665cd7a003--\r\n