typescript - Jag får "Http failure response for (unknown url): 0 Unknown Error" istället för det faktiska felmeddelandet i Angular
Jag använder Angular 4 HttpClient för att skicka förfrågningar till en extern tjänst. Det är en mycket standardinställning:
this.httpClient.get(url).subscribe(response => {
//do something with response
}, err => {
console.log(err.message);
}, () => {
console.log('completed');
}
Problemet är att när förfrågan misslyckas ser jag ett generiskt Http failure response for (unknown url): 0 Unknown Error-meddelande i konsolen. Under tiden, när jag granskar den misslyckade förfrågan i Chrome, kan jag se att svarstatusen är 422, och i fliken ”förhandsgranskning” ser jag det faktiska meddelandet som beskriver orsaken till misslyckandet.
Hur får jag åtkomst till det faktiska svarsmeddelandet som jag kan se i Chrome Dev Tools?
Här är en skärmdump som visar problemet:
Svar #1
Problemet var relaterat till CORS. Jag märkte att det fanns ett annat fel i Chromes konsol:
Ingen 'Access-Control-Allow-Origin'-rubrik finns på den begärda resursen. Ursprung 'http://localhost:4200' har därför inte tillåtelse att få åtkomst. Svaret hade HTTP-statuskod 422.
Detta innebär att svaret från backend-servern saknade Access-Control-Allow-Origin-headern även om backend nginx var konfigurerad för att lägga till dessa headers till svaren med add_header-direktivet.
Men denna direktiv lägger bara till rubriker när svarskoden är 20X eller 30X. Vid fel-svar saknades rubrikerna. Jag var tvungen att använda always-parametern för att säkerställa att rubriken läggs till oavsett svarskod:
add_header 'Access-Control-Allow-Origin' 'http://localhost:4200' always;När backenden var korrekt konfigurerad kunde jag få tillgång till det faktiska felmeddelandet i Angular-koden.
Svar #2
Om någon annan skulle bli lika vilse som jag var... Mina problem berodde INTE på CORS (jag har full kontroll över servern/servrarna och CORS var korrekt konfigurerat!).
Mitt problem berodde på att jag använder Android plattformsnivå 28 som som standard inaktiverar okrypterad nätverkskommunikation och jag försökte utveckla appen som pekar på min laptops IP (som kör API-servern). API-bas-URL:en är något i stil med http://[LAPTOP_IP]:8081. Eftersom det inte är https, blockerar Android WebView helt nätverksöverföringen mellan telefonen/emulatorn och servern på min laptop. För att fixa detta:
Lägg till en nätverkssäkerhetskonfiguration
Ny fil i projektet: 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>
OBS: Detta bör användas med försiktighet eftersom det tillåter all klartext från din app (inget tvingas använda https). Du kan begränsa det ytterligare om du vill.
Referera till konfigurationen i huvudconfig.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>
Det är allt! Därifrån byggde jag om APK-filen och appen kunde nu kommunicera både från emulatorn och telefonen.
Mer info om nätverkssäkerhet: https://developer.android.com/training/articles/security-config.html#CleartextTrafficPermitted
Svar #3
Om du använder .NET Core-applikation kan denna lösning hjälpa!
Dessutom kanske detta inte är ett Angular- eller annat begäran-fel i din frontend-applikation
Först måste du lägga till Microsoft CORS Nuget-paketet:
Install-Package Microsoft.AspNetCore.Cors
Du behöver sedan lägga till CORS-tjänsterna i din startup.cs. I din ConfigureServices-metod bör du ha något liknande följande:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
}
Nästa steg är att lägga till CORS-mellanmjukvara i din app. I din startup.cs bör du ha en Configure-metod. Du behöver ha den på ett sätt som liknar detta:
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
app.UseCors( options =>
options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseMvc();
}
Lambda för alternativen är ett flytande API så du kan lägga till/ta bort alla extra alternativ du behöver. Du kan faktiskt använda alternativet "AllowAnyOrigin" för att acceptera vilken domän som helst, men jag rekommenderar starkt att du inte gör detta eftersom det öppnar upp för cross-origin-anrop från vem som helst. Du kan också begränsa cross-origin-anrop till deras HTTP-metod (GET/PUT/POST etc.), så att du endast exponerar GET-anrop över domäner etc.
Svar #4
fungerar för mig efter att ha stängt av annonsblockerings-tillägget i Chrome, detta fel uppstår ibland på grund av något som blockerar http i webbläsaren

