Я получаю «Ответ об ошибке HTTP для (неизвестный URL): 0 Неизвестная ошибка» вместо фактического сообщения об ошибке в Angular


121

Я использую Angular 4 HttpClientдля отправки запросов во внешнюю службу. Это очень стандартная установка:

this.httpClient.get(url).subscribe(response => {
  //do something with response
}, err => {
  console.log(err.message);
}, () => {
  console.log('completed');
}

Проблема в том, что когда запрос не выполняется, я вижу Http failure response for (unknown url): 0 Unknown Errorв консоли общее сообщение. Между тем, когда я проверяю неудавшийся запрос в chrome, я вижу статус ответа 422, а на вкладке «предварительный просмотр» я вижу фактическую причину сбоя в сообщении.

Как мне получить доступ к фактическому ответному сообщению, которое я вижу в инструментах Chrome dev?

Вот скриншот, демонстрирующий проблему: введите описание изображения здесь


попробуйте зарегистрировать весь errобъект - не толькоmessage
— Павел Агарков

Я столкнулся с той же проблемой и собирался создать вопрос для этого тоже, вот полный объект ошибки
— Мехди Бенмоха

1
Или лучше {"headers": {"normalizedNames": {}, "lazyUpdate": null, "headers": {}}, "status": 0, "statusText": "Неизвестная ошибка", "url": null, "ok": false, "name": "HttpErrorResponse", "message": "Ответ HTTP с ошибкой для (неизвестный URL): 0 Неизвестная ошибка", "error": {"isTrusted": true}}
— Мехди Бенмоха,

@PavelAgarkov, дело не в логировании только сообщения. Полученный мной HttpErrorResponse просто не содержит фактического сообщения об ошибке. Вот скриншот проблемы. Вы можете видеть, что в журнале ошибок есть сообщение "... неизвестная ошибка ...", но когда вы посмотрите на предварительный просмотр ответа на запрос выше, вы увидите фактическое содержательное сообщение.
— grdl 08

Вы пользуетесь услугами сервисного работника?
— Mackelito

Ответы:


97

Проблема была связана с CORS . Я заметил, что в консоли Chrome произошла еще одна ошибка:

На запрошенном ресурсе отсутствует заголовок Access-Control-Allow-Origin. Происхождение « HTTP: // локальный: 4200 », следовательно , не имеет права доступа. Ответ имел код состояния HTTP 422.

Это означает, что в ответе внутреннего сервера отсутствовал Access-Control-Allow-Originзаголовок, хотя серверный nginx был настроен на добавление этих заголовков в ответы с помощью add_headerдирективы .

Однако эта директива добавляет заголовки только тогда, когда код ответа равен 20X или 30X. В сообщениях об ошибках отсутствовали заголовки. Мне нужно было использовать alwaysпараметр, чтобы убедиться, что заголовок добавлен независимо от кода ответа:

add_header 'Access-Control-Allow-Origin' 'http://localhost:4200' always;

Как только бэкэнд был правильно настроен, я мог получить доступ к фактическому сообщению об ошибке в коде Angular.


также следующая ссылка может быть полезна для включения CORS: docs.microsoft.com/en-us/aspnet/web-api/overview/security/…
— Bobs

11
где нужно добавить эту строку?
— Омид

1
как добавить слово «всегда» к функции .use в express.js? Обычно структура выглядит так: app.use (function (req, res, next) {res.header ("Access-Control-Allow-Origin", " localhost: 4200" );…}); Как видите, res.header допускает два параметра ... управляющую строку и значение. Я пытался добавить «всегда» разными способами, но все они, похоже, терпели неудачу. Какие-либо предложения?
— AppDreamer

@grdl, где нужно добавить строку add_header?
— sattva_venu

где добавить эту строчку? Я использую php для своего api
— Мустафа UYSAL

19

В случае, если кто-то еще окажется таким же потерянным, как и я ... Мои проблемы НЕ были связаны с CORS (я полностью контролирую сервер (ы), и CORS был настроен правильно!).

Моя проблема заключалась в том, что я использую платформу Android уровня 28, которая по умолчанию отключает сетевую связь в открытом виде, и я пытался разработать приложение, которое указывает на IP-адрес моего ноутбука (на котором запущен сервер API). Базовый URL-адрес API выглядит примерно так : http: // [LAPTOP_IP]: 8081 . Поскольку это не https , android webview полностью блокирует xfer сети между телефоном / эмулятором и сервером на моем ноутбуке. Чтобы это исправить:

Добавить конфигурацию сетевой безопасности

Новый файл в проекте: resources / android / xml / network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <!-- Set application-wide security config -->
  <base-config cleartextTrafficPermitted="true"/>
</network-security-config>

ПРИМЕЧАНИЕ. Это следует использовать осторожно, так как это разрешит весь открытый текст из вашего приложения (ничто не заставляет использовать https). Вы можете ограничить его, если хотите.

Ссылка на конфигурацию в основном config.xml

<platform name="android">
    ...
    <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
        <application android:networkSecurityConfig="@xml/network_security_config" />
    </edit-config>
    <resource-file src="resources/android/xml/network_security_config.xml" target="app/src/main/res/xml/network_security_config.xml" />
    ....
</platform>

Это оно! Оттуда я восстановил APK, и теперь приложение могло связываться как с эмулятором, так и с телефона.

Дополнительная информация о сетевой сек: https://developer.android.com/training/articles/security-config.html#CleartextTrafficPermitted


Большое спасибо! Я также использовал URL-адрес "http". Изменил его на «https», и все заработало. Кстати, просто изменить URL-адрес на https не получится, для этого нужен сертификат. Сервер, который я использовал, поддерживает оба, так что мне было проще. В любом случае, спасибо большое!
— Xonshiz

1
да ... для меня это не о .... слишком открытом тексте , потому что я использую http.. это бы не быть проблемой , если я использую https.... но в случае , если я все еще хочу использовать http, я сразу добавить android:usesCleartextTraffic="true"в applicationтеге в AndroidManifest.xml. ..и это работает .... спасибо за упоминание о cleartext...
— Syamsoul Azrien

Как я могу включить это при загрузке Spring? Прошу прощения, если вопрос слишком тривиален, но я новичок и не могу найти никаких решений в Интернете
— Асма Рахим Али Джафри

13

работает для меня после отключения расширения блокировки рекламы в Chrome, эта ошибка иногда появляется из-за того, что что-то блокирует http в браузере

введите описание изображения здесь


1
для меня это было uBlock Origin , который заблокировал загрузку файла с «аналитикой» в этом имени
— Marke

9

Если вы используете приложение .NET Core, это решение может помочь!

Более того, это может быть не ошибка Angular или другая ошибка запроса в вашем клиентском приложении.

Во-первых, вам нужно добавить пакет Microsoft CORS Nuget:

Install-Package Microsoft.AspNetCore.Cors

Затем вам нужно добавить службы CORS в файл startup.cs. В вашем методе ConfigureServices должно быть что-то похожее на следующее:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors();
}

Затем добавьте в свое приложение промежуточное ПО CORS. В вашем startup.cs у вас должен быть метод настройки. Вам нужно, чтобы это было примерно так:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
ILoggerFactory loggerFactory)
{
    app.UseCors( options => 
    options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
    app.UseMvc();
}

Лямбда параметров - это удобный API, поэтому вы можете добавлять / удалять любые дополнительные параметры, которые вам нужны. Фактически вы можете использовать опцию «AllowAnyOrigin», чтобы принять любой домен, но я настоятельно рекомендую вам не делать этого, поскольку он открывает вызовы из разных источников от кого-либо. Вы также можете ограничить перекрестные вызовы источников их HTTP-методом (GET / PUT / POST и т. Д.), Чтобы вы могли только открывать перекрестные доменные вызовы GET и т. Д.


5

Эта ошибка возникала у меня в Firefox, но не в Chrome при локальной разработке, и оказалось, что Firefox не доверяет моему локальному сертификату ssl API (который недействителен, но я добавил его в свое локальное хранилище сертификатов, что позволило хром доверять ему но не ff). Непосредственный переход к API и добавление исключения в Firefox устранили проблему.


1
Я просмотрел несколько ответов CORS, и один за другим каждый из них не предлагал решения при использовании Firefox. Я посмотрел на этот пост и подумал: «Да нет, но у меня нет идей, какого черта», и, конечно же, это сработало. Спасибо вам большое!
— Аарон Джордан

@frax, у меня точно такой же был случай! Спасибо! :)
— W92

5

Для меня это было вызвано исключением JsonSerializerException на стороне сервера.

Произошло необработанное исключение при выполнении запроса Newtonsoft.Json.JsonSerializationException: обнаружен цикл самореференции с типом ...

Клиент сказал:

POST http://localhost:61495/api/Action net::ERR_INCOMPLETE_CHUNKED_ENCODING
ERROR HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false, …}

Упрощение типа ответа за счет устранения петель решило проблему.


2

Если вы используете Laravel в качестве Backend, отредактируйте файл .htaccess, просто вставив этот код, чтобы решить проблему CROS в вашем проекте Angular или IONIC.

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"

6
Никогда не позволяйте "*"! В общем, вы знаете, кто разговаривает с вашим сервером, и вам следует явно указать его хост.
— itmuckel

@itmuckel, но если вы делаете приложение для Android, хост не известен. Будет ли каждый мобильный телефон использовать ваши услуги, я прав?
— Martin

2
нам нужно было использовать cordova-plugin-advanced-http и @ ionic / native wrapper для нативных HTTP-вызовов с устройства вместо использования ajax-вызова на основе браузера. @Martin
— user323774

2

Аналогичная ошибка может возникнуть, если вы не предоставили действующий сертификат клиента и токен, который понимает ваш сервер:

Ошибка:

Ответ об ошибке HTTP для (неизвестный URL): 0 Неизвестная ошибка

Пример кода:

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

class MyCls1 {

  constructor(private http: HttpClient) {
  }

  public myFunc(): void {

    let http: HttpClient;

    http.get(
      'https://www.example.com/mypage',
      {
        headers:
          new HttpHeaders(
            {
              'Content-Type': 'application/json',
              'X-Requested-With': 'XMLHttpRequest',
              'MyClientCert': '',        // This is empty
              'MyToken': ''              // This is empty
            }
          )
      }
    ).pipe( map(res => res), catchError(err => throwError(err)) );
  }

}

Обратите внимание, что оба MyClientCert& MyTokenявляются пустыми строками, отсюда и ошибка.
MyClientCert& MyTokenможет быть любым именем, понятным вашему серверу.


Я использую этот код в своем ионном приложении. мое ионное приложение используется в качестве индекса на моем сайте. но эти уловки мне не помогут. кажется, мой apis в laravel нуждается в конфигурации, возможно, в ngnix или laravel или моем хосте докера ... я использовал промежуточное программное обеспечение cors для включения cors, и он работал на моем локальном компьютере с http, но при развертывании на докере не мог вызвать мой api с https
— saber tabatabaee yazdi

когда я вызываю свой отдых apis из http, они работали, но при вызове https они не отвечали моим клиентам. и вернуть ошибку смешанного типа. Я думаю, что есть ошибка сертификата или что-то вроде конфигурации nginx или .htaccess, потому что я добавляю промежуточное ПО cors для cors, и все работает хорошо без https. мой клиент размещен на http-вызове http-результат в порядке. но когда мой клиентский хост на https и вызов https произошли ошибки
— saber tabatabaee yazdi

Хорошо, одно из решений - перейдите по URL-адресу https: //, который у вас есть, и щелкните значок замка рядом с https, загрузите сертификат в файл, прочтите этот файл через import / require / fs, затем дайте / передайте это строка сертификата на вызов по URL-адресу, тогда он будет работать.
— Манохар Редди Поредди

2

Я использую расширения ASP.NET SPA, которые создают мне прокси на портах 5000 и 5001, которые передаются на порт 4200 Angular во время разработки.

Я правильно настроил CORS для https-порта 5001, и все было в порядке, но я случайно перешел на старую закладку, которая была для порта 5000. Затем внезапно возникло это сообщение. Как другие говорили в консоли, появилось сообщение об ошибке «предполетная».

Итак, независимо от вашей среды, если вы используете CORS, убедитесь, что у вас указаны все порты - поскольку хост и порт имеют значение.


2

Я получал именно это сообщение всякий раз, когда выполнение моих запросов занимало более 2 минут. Браузер отключился от запроса, но запрос на серверной части продолжался, пока не был завершен. Сервер (в моем случае веб-API ASP.NET) не обнаружил разъединение.

После целого дня поиска я наконец нашел этот ответ , объяснив, что если вы используете конфигурацию прокси , у него по умолчанию тайм-аут 120 секунд (или 2 минуты).

Итак, вы можете отредактировать конфигурацию прокси и установить все, что вам нужно:

{
  "/api": {
    "target": "http://localhost:3000",
    "secure": false,
    "timeout": 6000000
  }
}

Теперь я использовал agentkeepalive, чтобы заставить его работать с аутентификацией NTLM , и не знал, что тайм-аут агента не имеет ничего общего с тайм-аутом прокси, поэтому оба должны быть установлены. Мне потребовалось время, чтобы осознать это, поэтому вот пример:

const Agent = require('agentkeepalive');

module.exports = {
    '/api/': {
        target: 'http://localhost:3000',
        secure: false,
        timeout: 6000000,          // <-- this is needed as well
        agent: new Agent({
            maxSockets: 100,
            keepAlive: true,
            maxFreeSockets: 10,
            keepAliveMsecs: 100000,
            timeout: 6000000,      // <-- this is for the agentkeepalive
            freeSocketTimeout: 90000
        }),
        onProxyRes: proxyRes => {
            let key = 'www-authenticate';
            proxyRes.headers[key] = proxyRes.headers[key] &&
                proxyRes.headers[key].split(',');
        }
    }
};

2

Для меня это была проблема браузера, так как мои запросы нормально работали в Postman.

Оказывается, по какой-то причине Firefox и Chrome заблокировали запросы, идущие на порт 6000, после того как я изменил порт API ASP.NET на 4000, ошибка изменилась на известную ошибку CORS, которую я мог исправить.

Chrome по крайней мере показал мне, ERR_UNSAFE_PORTчто дало мне понять, что может быть не так.


1

Если у вас есть правильный заголовок cors. Возможно, в вашей корпоративной сети отсутствует заголовок cors. Если веб-сайт доступен извне, попробуйте получить к нему доступ из-за пределов своей сети, чтобы проверить, не вызывает ли сеть проблема - хорошая идея независимо от причины.


1

В ядре asp.net, если ваш контроллер api не имеет вызываемой аннотации [AllowAnonymous], добавьте ее над именем вашего контроллера, например

[ApiController]
    [Route("api/")]
    [AllowAnonymous]
    public class TestController : ControllerBase

0

Не такой старый, как другие вопросы, но я просто боролся с этим в приложении Ionic-Laravel, и здесь ничего не работает (и другие сообщения), поэтому я установил дополнение https://github.com/barryvdh/laravel-cors в Laravel и запустился, и он работает очень хорошо.


0

Моя была вызвана недопустимыми отношениями в моделях, которые я пытался запросить. Выяснилось путем отладки ответа, что он разбился в отношении.


0

Для меня это не было проблемой. Было поле типа DateTime в БД, которое имеет значение (0000-00-00), и моя модель не может правильно привязать это свойство, поэтому я изменил на допустимое значение, например (2019-08-12).

Я использую ядро ​​.net, OData v4 и MySql (коннектор EF pomelo)


0

Добавьте эти коды в файл подключения

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT,GET,POST,DELETE");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");

0

Если это служба узла, попробуйте шаги, описанные здесь

По сути, это ошибка общего доступа к ресурсам (CORS). Подробнее о таких ошибках здесь .

Как только я обновил службу узлов, добавив следующие строки, все заработало:

let express = require("express");
let app = express();

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");    
    next();
  });

-2

Моя ошибка заключалась в том, что файл был слишком большим (ядро dotnet, похоже, имеет ограничение @ ~ 25 МБ). настройка

  • maxAllowedContentLength до 4294967295 (максимальное значение uint) в web.config
  • украшение действия контроллера [DisableRequestSizeLimit]
  • services.Configure (options => {options.MultipartBodyLengthLimit = 4294967295;}); в Startup.cs

решил проблему для меня.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.