Saya mendapatkan "Respons kegagalan http untuk (url tidak dikenal): 0 Kesalahan Tidak Diketahui" alih-alih pesan kesalahan sebenarnya di Angular

121

Saya menggunakan Angular 4 HttpClientuntuk mengirim permintaan ke layanan eksternal. Ini adalah pengaturan yang sangat standar:

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

Masalahnya adalah, ketika permintaan gagal saya melihat Http failure response for (unknown url): 0 Unknown Errorpesan umum di konsol. Sementara itu, ketika saya memeriksa permintaan yang gagal di chrome, saya dapat melihat status tanggapannya adalah 422, dan di tab "pratinjau" saya melihat pesan sebenarnya yang menjelaskan penyebab kegagalan.

Bagaimana cara mengakses pesan tanggapan sebenarnya yang dapat saya lihat di alat dev chrome?

Berikut tangkapan layar yang menunjukkan masalahnya: masukkan deskripsi gambar di sini

grdl
sumber
mencoba untuk mencatat seluruh errobjek - tidak hanyamessage
Pavel Agarkov
Saya menghadapi masalah yang sama dan akan membuat pertanyaan untuk ini juga, berikut objek kesalahan lengkapnya: gist.github.com/GO3LIN/7cffc3b0aa1f24d3e23e28cc907237fc
Mehdi Benmoha
1
Atau lebih baik {"headers": {"normalizedNames": {}, "lazyUpdate": null, "headers": {}}, "status": 0, "statusText": "Unknown Error", "url": null, "ok": false, "name": "HttpErrorResponse", "message": "Tanggapan kegagalan http untuk (url tidak dikenal): 0 Kesalahan Tidak Diketahui", "error": {"isTrusted": true}}
Mehdi Benmoha
@PavelAgarkov, Ini bukan tentang mencatat hanya pesan. HttpErrorResponse yang saya terima tidak berisi pesan kesalahan sebenarnya. Berikut tangkapan layar masalahnya. Anda dapat melihat di sana bahwa kesalahan yang saya catat memiliki pesan yang mengatakan "... kesalahan yang tidak diketahui ..." tetapi ketika Anda melihat pratinjau respons permintaan di atas, Anda dapat melihat pesan yang sebenarnya dan bermakna.
grdl
Apakah Anda menggunakan pekerja layanan?
Mackelito

Jawaban:

96

Masalahnya terkait dengan CORS . Saya melihat bahwa ada kesalahan lain di konsol Chrome:

Tidak ada header 'Access-Control-Allow-Origin' yang ada di resource yang diminta. Oleh karena itu, asal ' http: // localhost: 4200 ' tidak diizinkan untuk diakses. Responsnya memiliki kode status HTTP 422.`

Ini berarti respons dari server backend tidak memiliki Access-Control-Allow-Originheader meskipun nginx backend dikonfigurasi untuk menambahkan header tersebut ke respons dengan add_headerdirektif .

Namun, arahan ini hanya menambahkan header jika kode respons 20X atau 30X. Pada tanggapan kesalahan, header hilang. Saya perlu menggunakan alwaysparameter untuk memastikan header ditambahkan terlepas dari kode respons:

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

Setelah backend dikonfigurasi dengan benar, saya dapat mengakses pesan kesalahan sebenarnya dalam kode Angular.

grdl
sumber
juga tautan berikut dapat membantu untuk mengaktifkan CORS: docs.microsoft.com/en-us/aspnet/web-api/overview/security/…
Bobs
11
dimana baris ini harus ditambahkan?
Omid Ataollahi
1
bagaimana Anda menambahkan 'selalu' ke fungsi express.js .use? Biasanya strukturnya adalah: app.use (function (req, res, next) {res.header ("Access-Control-Allow-Origin", " localhost: 4200" );…}); Seperti yang Anda lihat, res.header memungkinkan dua parameter ... string kontrol dan nilai. Saya telah mencoba menambahkan 'selalu' dengan berbagai cara tetapi semuanya tampaknya gagal. Ada saran?
AppDreamer
@grdl, di mana baris add_header harus ditambahkan?
sattva_venu
dimana menambahkan baris ini? Saya menggunakan php untuk api saya
Mustafa UYSAL
19

Jika ada orang lain yang akhirnya tersesat seperti saya ... Masalah saya BUKAN karena CORS (Saya memiliki kendali penuh atas server dan CORS telah dikonfigurasi dengan benar!).

Masalah saya adalah karena saya menggunakan platform Android level 28 yang menonaktifkan komunikasi jaringan cleartext secara default dan saya mencoba mengembangkan aplikasi yang mengarah ke IP laptop saya (yang menjalankan server API). URL dasar API adalah seperti http: // [LAPTOP_IP]: 8081 . Karena bukan https , tampilan web android sepenuhnya memblokir xfer jaringan antara ponsel / emulator dan server di laptop saya. Untuk memperbaikinya:

Tambahkan konfigurasi keamanan jaringan

File baru dalam proyek: 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>

CATATAN: Ini harus digunakan dengan hati-hati karena akan mengizinkan semua teks bebas dari aplikasi Anda (tidak ada yang dipaksa untuk menggunakan https). Anda dapat membatasinya lebih lanjut jika Anda mau.

Referensi konfigurasi di config.xml utama

<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>

Itu dia! Dari sana saya membangun kembali APK dan aplikasi sekarang dapat berkomunikasi dari emulator dan telepon.

Info lebih lanjut tentang jaringan sec: https://developer.android.com/training/articles/security-config.html#CleartextTrafficPermitted

kuyu
sumber
Terima kasih banyak! Saya juga menggunakan url "http". Mengubahnya menjadi "https" dan berhasil. Btw, hanya mengubah url ke https tidak akan berfungsi, Anda memerlukan sertifikat untuk menanganinya. Server yang saya gunakan mendukung keduanya, jadi lebih mudah bagi saya. Ngomong-ngomong, Terima Kasih Ton!
Xonshiz
1
ya ... bagi saya ini adalah tentang teks-jelas terlalu .... karena saya menggunakan http.. itu tidak akan menjadi masalah jika saya menggunakan https.... tapi dalam kasus saya masih ingin menggunakan http, saya langsung menambahkan android:usesCleartextTraffic="true"di applicationtag di AndroidManifest.xml. ..dan berhasil .... terima kasih telah menyebutkan tentang cleartext...
Syamsoul Azrien
Bagaimana saya bisa mengaktifkan ini di Spring boot? Saya minta maaf jika pertanyaannya terlalu sepele tetapi saya seorang pemula dan saya tidak dapat menemukan solusi apa pun secara online
Asma Rahim Ali Jafri
13

berfungsi untuk saya setelah mematikan ekstensi blokir iklan di chrome, kesalahan ini kadang-kadang muncul karena sesuatu yang memblokir http di browser

masukkan deskripsi gambar di sini

Dwi Yanuar Ilham
sumber
1
bagi saya itu uBlock Origin yang memblokir pengunduhan file dengan 'analytics' di namanya
marke
9

Jika Anda menggunakan aplikasi .NET Core, solusi ini mungkin membantu!

Selain itu, ini mungkin bukan Angular atau kesalahan permintaan lainnya di aplikasi front end Anda

Pertama, Anda harus menambahkan paket Microsoft CORS Nuget:

Install-Package Microsoft.AspNetCore.Cors

Kemudian Anda perlu menambahkan layanan CORS di startup.cs Anda. Dalam metode ConfigureServices, Anda harus memiliki sesuatu yang mirip dengan berikut ini:

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

Selanjutnya, tambahkan middleware CORS ke aplikasi Anda. Di startup.cs Anda, Anda harus memiliki metode Konfigurasi. Anda harus memilikinya seperti ini:

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

Opsi lambda adalah API yang lancar sehingga Anda dapat menambah / menghapus opsi tambahan yang Anda butuhkan. Anda sebenarnya dapat menggunakan opsi "AllowAnyOrigin" untuk menerima domain apa pun, tetapi saya sangat menyarankan Anda untuk tidak melakukan ini karena ini akan membuka panggilan lintas sumber dari siapa pun. Anda juga dapat membatasi panggilan lintas sumber ke Metode HTTP mereka (GET / PUT / POST, dll.), Sehingga Anda hanya dapat mengekspos panggilan GET lintas domain, dll.

sathish
sumber
5

Kesalahan ini terjadi pada saya di Firefox tetapi bukan Chrome saat mengembangkan secara lokal, dan itu ternyata disebabkan oleh Firefox tidak mempercayai sertifikat ssl API lokal saya (yang tidak valid, tetapi saya telah menambahkannya ke toko sertifikat lokal saya, yang memungkinkan chrome mempercayainya tetapi tidak ff). Menavigasi ke API secara langsung dan menambahkan pengecualian di Firefox memperbaiki masalah tersebut.

frax
sumber
1
Saya telah melalui beberapa jawaban CORS dan satu demi satu masing-masing tidak memberikan solusi saat menggunakan Firefox. Saya melihat posting ini dan berpikir, "tidak mungkin ini tapi saya kehabisan ide apa" dan cukup yakin itu berhasil. Terima kasih banyak!
Aaron Jordan
@frax, saya punya kasus yang persis sama! Terima kasih! :)
W92
5

Bagi saya itu disebabkan oleh sisi server JsonSerializerException.

Pengecualian tidak tertangani telah terjadi saat menjalankan permintaan Newtonsoft.Json.JsonSerializationException: Loop referensi mandiri terdeteksi dengan tipe ...

Klien berkata:

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

Menyederhanakan jenis respons dengan menghilangkan loop memecahkan masalah.

Perrier
sumber
2

Jika Anda menggunakan Laravel sebagai Backend Anda, maka edit file .htaccess Anda hanya dengan menempelkan kode ini, untuk menyelesaikan masalah CROS di proyek Angular atau IONIC Anda

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
shirjeel khan
sumber
6
Anda tidak boleh mengizinkan "*"! Secara umum Anda tahu siapa yang berbicara dengan backend Anda dan Anda harus mengatur host mereka secara eksplisit.
itmuckel
@itmuckel tetapi jika Anda membuat aplikasi untuk android, hostnya tidak diketahui. Akankah setiap ponsel yang mengkonsumsi layanan Anda, apakah saya benar?
Martin
2
kami perlu menggunakan cordova-plugin-advanced-http dan @ ionic / native wrapper untuk memiliki panggilan http dari perangkat secara native daripada menggunakan panggilan ajax berbasis browser. @ Martin
user323774
2

Kesalahan serupa dapat terjadi, jika Anda tidak memberikan token dan sertifikat klien yang valid yang dipahami server Anda:

Kesalahan:

Respons kegagalan http untuk (url tidak diketahui): 0 Kesalahan Tidak Diketahui

Kode contoh:

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

}

Perhatikan bahwa MyClientCert& MyTokenadalah string kosong, oleh karena itu kesalahannya.
MyClientCert& MyTokendapat berupa nama apa pun yang dipahami server Anda.

Manohar Reddy Poreddy
sumber
saya menggunakan kode ini di aplikasi ionik saya. aplikasi ionik saya digunakan sebagai indeks di situs saya. tetapi trik ini tidak dapat membantu saya. tampaknya apis saya di laravel perlu konfigurasi mungkin di ngnix atau laravel atau host buruh pelabuhan saya ... saya menggunakan cors middleware untuk cors diaktifkan dan berfungsi di lokal saya dengan http tetapi ketika digunakan di buruh pelabuhan tidak dapat memanggil api saya dengan https
saber tabatabaee yazdi
ketika saya memanggil aplikasi istirahat saya dari http yang berfungsi tetapi ketika memanggil https mereka tidak menanggapi klien saya. dan mengembalikan kesalahan Jenis Campuran. Saya pikir ada kesalahan sertifikat atau sesuatu seperti konfigurasi nginx atau .htaccess karena saya menambahkan cors middleware untuk cors dan semuanya bekerja dengan baik tanpa https. klien saya dihosting di http call http hasilnya ok. tetapi ketika klien saya menghosting di https dan kesalahan panggilan https terjadi
saber tabatabaee yazdi
Ok, salah satu solusinya adalah, buka https: // url yang Anda miliki, dan klik ikon gembok di samping https, unduh sertifikat ke file, baca file itu melalui import / require / fs, lalu berikan / berikan string sertifikat ke panggilan ke url, maka itu akan berfungsi.
Manohar Reddy Poreddy
2

Saya menggunakan ASP.NET SPA Extensions yang membuatkan saya proxy pada port 5000 dan 5001 yang melewati port Angular 4200 selama pengembangan.

Saya telah mengatur CORS dengan benar untuk https port 5001 dan semuanya baik-baik saja, tetapi saya secara tidak sengaja membuka bookmark lama untuk port 5000. Lalu tiba-tiba pesan ini muncul. Seperti yang dikatakan orang lain di konsol, ada pesan kesalahan 'preflight'.

Jadi terlepas dari lingkungan Anda, jika Anda menggunakan CORS, pastikan Anda memiliki semua port yang ditentukan - karena host dan port keduanya penting.

Simon_Weaver
sumber
2

Saya mendapatkan pesan persis seperti itu setiap kali permintaan saya membutuhkan waktu lebih dari 2 menit untuk diselesaikan. Browser akan memutuskan sambungan dari permintaan, tetapi permintaan di backend terus berlanjut hingga selesai. Server (ASP.NET Web API dalam kasus saya) tidak akan mendeteksi pemutusan sambungan.

Setelah seharian mencari, saya akhirnya menemukan jawaban ini , menjelaskan bahwa jika Anda menggunakan konfigurasi proxy , ia memiliki batas waktu default 120 detik (atau 2 menit).

Jadi, Anda dapat mengedit konfigurasi proxy Anda dan mengaturnya ke apa pun yang Anda butuhkan:

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

Sekarang, saya menggunakan agentkeepalive untuk membuatnya berfungsi dengan otentikasi NTLM , dan tidak tahu bahwa batas waktu agen tidak ada hubungannya dengan batas waktu proxy, jadi keduanya harus disetel. Butuh beberapa saat bagi saya untuk menyadarinya, jadi inilah contohnya:

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
sumber
2

Bagi saya itu adalah masalah browser, karena permintaan saya berfungsi dengan baik di Postman.

Ternyata karena alasan tertentu, Firefox dan Chrome memblokir permintaan yang masuk ke porta 6000, setelah saya mengubah port API ASP.NET ke 4000, kesalahan berubah menjadi kesalahan CORS yang diketahui yang dapat saya perbaiki.

Chrome setidaknya menunjukkan kepada saya ERR_UNSAFE_PORTyang memberi saya petunjuk tentang apa yang salah.

Shahin Dohan
sumber
1

Jika Anda memiliki tajuk kors yang tepat. Jaringan perusahaan Anda mungkin melepaskan header cors. Jika situs web dapat diakses secara eksternal, coba akses dari luar jaringan Anda untuk memverifikasi apakah jaringan yang menyebabkan masalah - ide bagus apa pun penyebabnya.

N-makan
sumber
1

Di inti asp.net, Jika pengontrol api Anda tidak memiliki anotasi yang dipanggil [AllowAnonymous], tambahkan di atas nama pengontrol Anda seperti

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

Tidak setua pertanyaan lain, tetapi saya hanya berjuang dengan ini di aplikasi Ionic-Laravel, dan tidak ada yang berfungsi dari sini (dan posting lain), jadi saya menginstal https://github.com/barryvdh/laravel-cors pelengkap di Laravel dan memulai dan itu bekerja dengan cukup baik.

gersonmontenegro
sumber
0

Milik saya disebabkan oleh hubungan yang tidak valid dalam model yang saya coba tanyakan. Dipecahkan dengan men-debug respons yang mogok di relasi.

J. Kirk.
sumber
0

Bagi saya itu bukan masalah sudut. Adalah bidang tipe DateTime di DB yang memiliki nilai (0000-00-00) dan model saya tidak dapat mengikat properti itu dengan benar, jadi saya mengubahnya ke nilai yang valid seperti (2019-08-12).

Saya menggunakan .net core, OData v4 dan MySql (konektor EF pomelo)

Luis Lopez
sumber
0

Tambahkan Kode Ini di file koneksi Anda

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
sumber
0

Jika ini adalah layanan node, coba langkah-langkah yang diuraikan di sini

Pada dasarnya, ini adalah kesalahan Berbagi Sumber Daya Lintas Asal (CORS). Informasi lebih lanjut tentang kesalahan tersebut di sini .

Setelah saya memperbarui layanan node saya dengan baris berikut ini berfungsi:

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();
  });
Tinjuan kemarahan
sumber
-2

Kesalahan saya adalah bahwa file tersebut terlalu besar (inti dotnet tampaknya memiliki batas @ ~ 25Mb). Pengaturan

  • maxAllowedContentLength hingga 4294967295 (nilai maks uint) di web.config
  • mendekorasi aksi pengontrol dengan [DisableRequestSizeLimit]
  • services.Configure (options => {options.MultipartBodyLengthLimit = 4294967295;}); di Startup.cs

memecahkan masalah untuk saya.

Spikolynn
sumber