Ich erhalte die Meldung "HTTP-Fehlerantwort für (unbekannte URL): 0 Unbekannter Fehler" anstelle der eigentlichen Fehlermeldung in Angular

121

Ich verwende Angular 4 HttpClient, um Anfragen an einen externen Dienst zu senden. Es ist ein sehr Standard-Setup:

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

Das Problem ist, wenn die Anforderung fehlschlägt Http failure response for (unknown url): 0 Unknown Error, wird in der Konsole eine allgemeine Nachricht angezeigt. Wenn ich die fehlgeschlagene Anforderung in Chrome überprüfe, sehe ich, dass der Antwortstatus 422 lautet, und auf der Registerkarte "Vorschau" wird die tatsächliche Fehlerursache für die Beschreibung der Nachricht angezeigt.

Wie greife ich auf die tatsächliche Antwortnachricht zu, die in den Chrome Dev Tools angezeigt wird?

Hier ist ein Screenshot, der das Problem zeigt: Geben Sie hier die Bildbeschreibung ein

grdl
quelle
versuchen Sie, das gesamte errObjekt zu protokollieren - nicht nur dasmessage
Pavel Agarkov
Ich stehe vor dem gleichen Problem und wollte auch hier eine Frage stellen. Hier ist das vollständige Fehlerobjekt
Mehdi Benmoha,
1
Oder besser {"headers": {"normalizedNames": {}, "lazyUpdate": null, "headers": {}}, "status": 0, "statusText": "Unknown Error", "url": null, "ok": false, "name": "HttpErrorResponse", "message": "Http-Fehlerantwort für (unbekannte URL): 0 Unbekannter Fehler", "error": {"isTrusted": true}}
Mehdi Benmoha
@PavelAgarkov, es geht nicht nur darum, Nachrichten zu protokollieren. Die HttpErrorResponse, die ich erhalte, enthält einfach nicht die eigentliche Fehlermeldung. Hier ist ein Screenshot des Problems. Sie können dort sehen, dass der Fehler, den ich protokolliere, die Meldung "... unbekannter Fehler ..." enthält. Wenn Sie sich jedoch die Vorschau der Anforderungsantwort oben ansehen, sehen Sie die tatsächliche, aussagekräftige Meldung.
Grdl
Verwenden Sie einen Servicemitarbeiter?
Mackelito

Antworten:

96

Das Problem hing mit CORS zusammen . Ich habe festgestellt, dass in der Chrome-Konsole ein weiterer Fehler aufgetreten ist:

In der angeforderten Ressource ist kein Header 'Access-Control-Allow-Origin' vorhanden. Origin ' http: // localhost: 4200 ' ist daher kein Zugriff gestattet. Die Antwort hatte den HTTP-Statuscode 422.`

Dies bedeutet, dass der Antwort vom Backend-Server der Access-Control-Allow-OriginHeader fehlte , obwohl Backend-Nginx so konfiguriert wurde, dass diese Header zu den Antworten mit add_headerDirektive hinzugefügt werden .

Diese Anweisung fügt jedoch nur Header hinzu, wenn der Antwortcode 20X oder 30X ist. Bei Fehlerantworten fehlten die Header. Ich musste alwaysParameter verwenden, um sicherzustellen, dass der Header unabhängig vom Antwortcode hinzugefügt wird:

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

Sobald das Backend korrekt konfiguriert war, konnte ich auf die tatsächliche Fehlermeldung im Angular-Code zugreifen.

grdl
quelle
Auch der folgende Link kann hilfreich sein, um CORS zu aktivieren: docs.microsoft.com/en-us/aspnet/web-api/overview/security/…
Bobs
11
Wo soll diese Zeile hinzugefügt werden?
Omid Ataollahi
1
Wie fügt man einer express.js .use-Funktion 'immer' hinzu? Typischerweise lautet die Struktur: app.use (Funktion (req, res, next) {res.header ("Zugriffskontrolle-Zulassen-Ursprung", " localhost: 4200" );…}); Wie Sie sehen können, erlaubt der res.header zwei Parameter ... eine Steuerzeichenfolge und einen Wert. Ich habe versucht, "immer" auf verschiedene Arten hinzuzufügen, aber sie scheinen alle zu scheitern. Irgendwelche Vorschläge?
AppDreamer
@grdl, wo soll die Zeile add_header hinzugefügt werden?
sattva_venu
Wo diese Zeile hinzufügen? Ich benutze PHP für meine API
Mustafa UYSAL
19

Für den Fall, dass jemand anderes so verloren geht wie ich ... Meine Probleme waren NICHT auf CORS zurückzuführen (ich habe die volle Kontrolle über die Server und CORS wurde korrekt konfiguriert!).

Mein Problem war, dass ich die Android-Plattformstufe 28 verwende, die standardmäßig die Klartext-Netzwerkkommunikation deaktiviert, und ich habe versucht, die App zu entwickeln, die auf die IP meines Laptops verweist (auf der der API-Server ausgeführt wird). Die API-Basis-URL lautet ungefähr http: // [LAPTOP_IP]: 8081 . Da es sich nicht um https handelt , blockiert Android Webview das Netzwerk zwischen dem Telefon / Emulator und dem Server auf meinem Laptop vollständig. Um dies zu beheben:

Fügen Sie eine Netzwerksicherheitskonfiguration hinzu

Neue Datei im Projekt: 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>

HINWEIS: Dies sollte sorgfältig verwendet werden, da dadurch der gesamte Klartext Ihrer App zugelassen wird (nichts, was zur Verwendung von https gezwungen wird). Sie können es weiter einschränken, wenn Sie möchten.

Verweisen Sie auf die Konfiguration in der Datei main 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>

Das ist es! Von dort aus habe ich die APK neu erstellt und die App konnte nun sowohl vom Emulator als auch vom Telefon aus kommunizieren.

Weitere Informationen zu Netzwerksek: https://developer.android.com/training/articles/security-config.html#CleartextTrafficPermitted

haggy
quelle
Vielen Dank! Ich habe auch eine "http" -URL verwendet. Es wurde in "https" geändert und es hat funktioniert. Übrigens funktioniert es nicht, nur eine URL in https zu ändern. Dazu benötigen Sie ein Zertifikat. Der Server, den ich verwendet habe, unterstützt beide, daher war es für mich einfacher. Wie auch immer, vielen Dank!
Xonshiz
1
ja ... für mich ist es zu unverschlüsselt zu .... weil ich verwende http.. es wäre kein Problem, wenn ich verwende https.... aber im Fall , dass ich immer noch verwenden http, ich direkt hinzufügen android:usesCleartextTraffic="true"in - applicationTag in AndroidManifest.xml. ..und es funktioniert .... danke für die Erwähnung über cleartext...
Syamsoul Azrien
Wie kann ich dies im Spring Boot aktivieren? Es tut mir leid, wenn die Frage zu trivial ist, aber ich bin ein Anfänger und kann online keine Lösungen finden
Asma Rahim Ali Jafri
13

Wenn ich nach dem Deaktivieren der Anzeigenblockerweiterung in Chrome für mich arbeite, tritt dieser Fehler manchmal auf, weil etwas http im Browser blockiert

Geben Sie hier die Bildbeschreibung ein

Dwi Yanuar Ilham
quelle
1
Für mich war es uBlock Origin, das das Herunterladen von Dateien mit dem Namen 'Analytics' blockierte
Marke
9

Wenn Sie eine .NET Core-Anwendung verwenden, kann diese Lösung hilfreich sein!

Darüber hinaus ist dies möglicherweise kein Angular- oder anderer Anforderungsfehler in Ihrer Front-End-Anwendung

Zunächst müssen Sie das Microsoft CORS Nuget-Paket hinzufügen:

Install-Package Microsoft.AspNetCore.Cors

Anschließend müssen Sie die CORS-Dienste in Ihrer startup.cs hinzufügen. In Ihrer ConfigureServices-Methode sollten Sie Folgendes haben:

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

Fügen Sie als Nächstes die CORS-Middleware zu Ihrer App hinzu. In Ihrer startup.cs sollten Sie eine Configure-Methode haben. Sie müssen es ähnlich haben:

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

Die Option Lambda ist eine fließende API, mit der Sie zusätzliche Optionen hinzufügen / entfernen können, die Sie benötigen. Sie können die Option "AllowAnyOrigin" tatsächlich verwenden, um eine Domain zu akzeptieren. Ich empfehle jedoch dringend, dies nicht zu tun, da dadurch Cross-Origin-Anrufe von jedermann geöffnet werden. Sie können auch Ursprungsübergreifende Aufrufe auf ihre HTTP-Methode (GET / PUT / POST usw.) beschränken, sodass Sie nur domänenübergreifende GET-Aufrufe usw. verfügbar machen können.

sathish
quelle
5

Dieser Fehler trat bei der lokalen Entwicklung in Firefox, aber nicht in Chrome auf, und es stellte sich heraus, dass Firefox dem SSL-Zertifikat meiner lokalen API nicht vertraute (was nicht gültig ist, aber ich hatte es meinem lokalen Zertifikatspeicher hinzugefügt, der dies zuließ Chrom vertraue es aber nicht ff). Durch direktes Navigieren zur API und Hinzufügen einer Ausnahme in Firefox wurde das Problem behoben.

frax
quelle
1
Ich habe mehrere CORS-Antworten durchgesehen und eine nach der anderen hat bei der Verwendung von Firefox keine Lösung geliefert. Ich schaute auf diesen Beitrag und dachte: "Auf keinen Fall, aber ich habe keine Ahnung, was zum Teufel" und sicher hat es funktioniert. Ich danke dir sehr!
Aaron Jordan
@frax, ich hatte genau den gleichen Fall! Vielen Dank! :)
W92
5

Für mich wurde es durch eine serverseitige JsonSerializerException verursacht.

Beim Ausführen der Anforderung Newtonsoft.Json.JsonSerializationException ist eine nicht behandelte Ausnahme aufgetreten: Selbstreferenzierende Schleife mit Typ ...

Der Kunde sagte:

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

Die Vereinfachung des Antworttyps durch Eliminieren der Schleifen löste das Problem.

Perrier
quelle
2

Wenn Sie Laravel als Backend verwenden, bearbeiten Sie Ihre .htaccess-Datei, indem Sie nur diesen Code einfügen, um das Problem CROS in Ihrem Angular- oder IONIC-Projekt zu lösen

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
Shirjeel Khan
quelle
6
Sie sollten niemals "*" zulassen! Im Allgemeinen wissen Sie, wer mit Ihrem Backend spricht, und Sie sollten den Host explizit festlegen.
Itmuckel
@itmuckel aber wenn Sie eine App für Android den Host machen, ist es nicht bekannt. Wird jedes Handy sein, das Ihren Service nutzt, habe ich Recht?
Martin
2
Wir mussten Cordova-Plugin-Advanced-http und den @ ionic / native-Wrapper verwenden, um http-Aufrufe vom Gerät nativ zu erhalten, anstatt einen browserbasierten Ajax-Aufruf zu verwenden. @ Martin
Benutzer323774
2

Ein ähnlicher Fehler kann auftreten, wenn Sie kein gültiges Client-Zertifikat und Token angegeben haben, das Ihr Server versteht:

Error:

HTTP-Fehlerantwort für (unbekannte URL): 0 Unbekannter Fehler

Beispielcode:

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)) );
  }

}

Beachten Sie, dass beide MyClientCert& MyTokenleere Zeichenfolgen sind, daher der Fehler.
MyClientCert& MyTokenkann ein beliebiger Name sein, den Ihr Server versteht.

Manohar Reddy Poreddy
quelle
Ich benutze diesen Code in meiner ionischen App. Meine ionische App wird als Index auf meiner Website verwendet. Aber diese Tricks können mir nicht helfen. Anscheinend muss meine API in Laravel konfiguriert werden, möglicherweise in Ngnix oder Laravel oder auf meinem Docker-Host. Ich habe Cors Middleware für Cors aktiviert und es funktionierte auf meinem lokalen mit http, aber wenn es auf Docker bereitgestellt wird, kann ich meine API nicht mit https
saber tabatabaee yazdi
Wenn ich meine Rest-APIs von http anrufe, haben diese funktioniert, aber wenn ich https anrufe, haben sie nicht auf meine Kunden geantwortet. und geben Sie Mixed Type error zurück. Ich denke, es gibt Zertifikatfehler oder so etwas wie Nginx-Konfiguration oder .htaccess, weil ich Cors Middleware für Cors hinzufüge und alle Dinge ohne https gut funktionierten. Mein auf http gehosteter Client http Ergebnis ist in Ordnung. aber als mein Client auf https
hostete
Ok, eine Lösung ist, gehen Sie zu der https: // URL, die Sie haben, und klicken Sie auf das Schlosssymbol neben dem https, laden Sie das Zertifikat in eine Datei herunter, lesen Sie diese Datei über import / require / fs und geben / übergeben Sie diese Zertifikatzeichenfolge zum Aufruf der URL, dann funktioniert es.
Manohar Reddy Poreddy
2

Ich verwende ASP.NET SPA-Erweiterungen, die mir einen Proxy für die Ports 5000 und 5001 erstellen, die während der Entwicklung an Angulars Port 4200 weitergeleitet werden.

Ich hatte CORS korrekt für https Port 5001 eingerichtet und alles war in Ordnung, aber ich ging versehentlich zu einem alten Lesezeichen, das für Port 5000 war. Dann tauchte plötzlich diese Meldung auf. Wie andere in der Konsole gesagt haben, gab es eine "Preflight" -Fehlermeldung.

Wenn Sie CORS verwenden, stellen Sie unabhängig von Ihrer Umgebung sicher, dass alle Ports angegeben sind - da sowohl Host als auch Port von Bedeutung sind.

Simon_Weaver
quelle
2

Ich erhielt genau diese Nachricht, wenn meine Anfragen länger als 2 Minuten dauerten. Der Browser trennte sich von der Anforderung, aber die Anforderung im Backend wurde fortgesetzt, bis sie abgeschlossen war. Der Server (in meinem Fall die ASP.NET-Web-API) würde die Trennung nicht erkennen.

Nach einem ganzen Tag Suche habe ich endlich diese Antwort gefunden und erklärt, dass bei Verwendung der Proxy-Konfiguration das Standardzeitlimit 120 Sekunden (oder 2 Minuten) beträgt.

So können Sie Ihre Proxy-Konfiguration bearbeiten und auf die gewünschten Einstellungen einstellen:

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

Jetzt habe ich agentkeepalive verwendet, damit es mit der NTLM-Authentifizierung funktioniert , und wusste nicht, dass das Zeitlimit des Agenten nichts mit dem Zeitlimit des Proxys zu tun hat. Daher müssen beide festgelegt werden. Es hat eine Weile gedauert, bis mir das klar wurde. Hier ist ein Beispiel:

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(',');
        }
    }
};
Marcos Dimitrio
quelle
2

Für mich war es ein Browserproblem, da meine Anfragen in Postman gut funktionierten.

Es stellte sich heraus, dass Firefox und Chrome aus irgendeinem Grund Anfragen an den Port blockierten. Nachdem 6000ich den ASP.NET-API-Port auf 4000geändert hatte, änderte sich der Fehler in einen bekannten CORS-Fehler, den ich beheben konnte.

Chrome hat mir zumindest gezeigt, ERR_UNSAFE_PORTwas mir einen Hinweis darauf gab, was falsch sein könnte.

Shahin Dohan
quelle
1

Wenn Sie einen richtigen Cors-Header haben. Ihr Unternehmensnetzwerk entfernt möglicherweise den Cors-Header. Wenn auf die Website von außen zugegriffen werden kann, versuchen Sie, von außerhalb Ihres Netzwerks darauf zuzugreifen, um zu überprüfen, ob das Netzwerk das Problem verursacht - eine gute Idee, unabhängig von der Ursache.

N-aß
quelle
1

Wenn in asp.net core auf Ihrem API-Controller keine Annotation aufgerufen wird [AllowAnonymous], fügen Sie diese über Ihrem Controllernamen wie hinzu

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

Ist nicht so alt wie andere Fragen, aber ich habe gerade in einer Ionic-Laravel-App damit zu kämpfen, und von hier aus (und anderen Posts) funktioniert nichts mehr. Deshalb habe ich https://github.com/barryvdh/laravel-cors komplement in installiert Laravel und angefangen und es funktioniert ziemlich gut.

gersonmontenegro
quelle
0

Meins wurde durch eine ungültige Beziehung in den Modellen verursacht, die ich abfragen wollte. Dies wurde durch Debuggen der Antwort herausgefunden, die bei der Beziehung abgestürzt ist.

J. Kirk.
quelle
0

Für mich war es kein Winkelproblem. War ein Feld vom Typ DateTime in der Datenbank mit dem Wert (0000-00-00) und mein Modell kann diese Eigenschaft nicht korrekt binden, sodass ich auf einen gültigen Wert wie (2019-08-12) geändert habe.

Ich verwende .net Core, OData v4 und MySql (EF Pomelo Connector)

Luis Lopez
quelle
0

Fügen Sie diese Codes in Ihre Verbindungsdatei ein

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");
Abdelhakim Ezzahraoui
quelle
0

Wenn dies ein Knotendienst ist, führen Sie die hier beschriebenen Schritte aus

Grundsätzlich handelt es sich um einen CORS-Fehler (Cross-Origin Resource Sharing). Weitere Informationen zu solchen Fehlern finden Sie hier .

Nachdem ich meinen Knotendienst mit den folgenden Zeilen aktualisiert hatte, funktionierte er:

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();
  });
Faust der Wut
quelle
-2

Mein Fehler war, dass die Datei zu groß war (der Dotnet-Kern scheint ein Limit von ~ 25 MB zu haben). Rahmen

  • maxAllowedContentLength bis 4294967295 (Maximalwert von uint) in web.config
  • Dekorieren der Controller-Aktion mit [DisableRequestSizeLimit]
  • services.Configure (options => {options.MultipartBodyLengthLimit = 4294967295;}); in Startup.cs

löste das Problem für mich.

Spikolynn
quelle