Tôi nhận được “Phản hồi lỗi Http cho (url không xác định): 0 Lỗi không xác định” thay vì thông báo lỗi thực tế trong Angular


121

Tôi đang sử dụng Angular 4 HttpClientđể gửi yêu cầu đến dịch vụ bên ngoài. Đó là một thiết lập rất chuẩn:

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

Vấn đề là, khi yêu cầu không thành công, tôi thấy một Http failure response for (unknown url): 0 Unknown Errorthông báo chung trong bảng điều khiển. Trong khi đó, khi kiểm tra yêu cầu không thành công trong chrome, tôi có thể thấy trạng thái phản hồi là 422 và trong tab "xem trước", tôi thấy thông báo thực tế mô tả nguyên nhân thất bại.

Làm cách nào để truy cập thông báo phản hồi thực tế mà tôi có thể thấy trong các công cụ dành cho nhà phát triển chrome?

Đây là ảnh chụp màn hình chứng minh sự cố: nhập mô tả hình ảnh ở đây


cố gắng đăng nhập toàn bộ errđối tượng - không chỉ làmessage
Pavel Agarkov

Tôi đang phải đối mặt với cùng một vấn đề và đang diễn ra để tạo ra một câu hỏi cho quá này, đây là đối tượng err hoàn chỉnh: gist.github.com/GO3LIN/7cffc3b0aa1f24d3e23e28cc907237fc
Mehdi Benmoha

1
Hoặc tốt hơn là {"headers": {"normalizedNames": {}, "lazyUpdate": null, "headers": {}}, "status": 0, "statusText": "Unknown Error", "url": null, "ok": false, "name": "HttpErrorResponse", "message": "Http fail response for (url không xác định): 0 Unknown Error", "error": {"isTrusted": true}}
Mehdi Benmoha

@PavelAgarkov, Không phải chỉ ghi nhật ký thông báo. HttpErrorResponse mà tôi khôi phục chỉ không chứa thông báo lỗi thực sự. Đây là ảnh chụp màn hình của sự cố. Bạn có thể thấy ở đó lỗi tôi ghi có thông báo "... lỗi không xác định ..." nhưng khi bạn nhìn vào bản xem trước phản hồi yêu cầu ở trên, bạn có thể thấy thông báo thực tế, có ý nghĩa.
grdl

Bạn đang sử dụng một nhân viên dịch vụ?
Mackelito

Câu trả lời:


96

Vấn đề liên quan đến CORS . Tôi nhận thấy rằng có một lỗi khác trong bảng điều khiển Chrome:

Không có tiêu đề 'Access-Control-Allow-Origin' có trên tài nguyên được yêu cầu. Nguồn gốc ' http: // localhost: 4200 ' do đó không được phép truy cập. Phản hồi có mã trạng thái HTTP 422. '

Điều này có nghĩa là phản hồi từ máy chủ phụ trợ bị thiếu Access-Control-Allow-Origintiêu đề mặc dù nginx phụ trợ đã được định cấu hình để thêm các tiêu đề đó vào các phản hồi có add_headerchỉ thị .

Tuy nhiên, chỉ thị này chỉ thêm tiêu đề khi mã phản hồi là 20X hoặc 30X. Khi phản hồi lỗi, các tiêu đề bị thiếu. Tôi cần sử dụng alwaystham số để đảm bảo rằng tiêu đề được thêm vào bất kể mã phản hồi:

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

Sau khi chương trình phụ trợ được định cấu hình chính xác, tôi có thể truy cập thông báo lỗi thực tế trong mã Angular.


cũng liên kết sau có thể hữu ích để bật CORS: docs.microsoft.com/en-us/aspnet/web-api/overview/security/…
Bobs

11
dòng này nên được thêm vào đâu?
Omid Ataollahi

1
làm cách nào để bạn thêm 'always' vào hàm express.js .use? Cấu trúc điển hình là: app.use (function (req, res, next) {res.header ("Access-Control-Allow-Origin", " localhost: 4200" );…}); Như bạn có thể thấy, res.header cho phép hai tham số ... một chuỗi điều khiển và một giá trị. Tôi đã cố gắng thêm 'always' bằng nhiều cách khác nhau nhưng dường như tất cả đều thất bại. Bất kỳ đề xuất?
AppDreamer

@grdl, dòng add_header nên được thêm vào đâu?
sattva_venu

thêm dòng này ở đâu? Tôi sử dụng php cho api của mình
Mustafa UYSAL

19

Trong trường hợp bất kỳ ai khác kết thúc như tôi đã mất ... Vấn đề của tôi KHÔNG phải do CORS (Tôi có toàn quyền kiểm soát (các) máy chủ và CORS đã được định cấu hình chính xác!).

Vấn đề của tôi là do tôi đang sử dụng nền tảng Android cấp độ 28, tính năng này sẽ tắt truyền thông mạng văn bản rõ ràng theo mặc định và tôi đang cố gắng phát triển ứng dụng trỏ đến IP máy tính xách tay của tôi (đang chạy máy chủ API). URL cơ sở của API giống như http: // [LAPTOP_IP]: 8081 . Vì không phải https , nên webview android chặn hoàn toàn mạng xfer giữa điện thoại / trình giả lập và máy chủ trên máy tính xách tay của tôi. Để khắc phục điều này:

Thêm cấu hình bảo mật mạng

Tệp mới trong dự án: 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>

LƯU Ý: Điều này nên được sử dụng cẩn thận vì nó sẽ cho phép tất cả văn bản rõ ràng từ ứng dụng của bạn (không có gì buộc phải sử dụng https). Bạn có thể hạn chế nó hơn nữa nếu bạn muốn.

Tham khảo cấu hình trong config.xml chính

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

Đó là nó! Từ đó, tôi đã xây dựng lại APK và ứng dụng hiện có thể giao tiếp từ cả trình giả lập và điện thoại.

Thông tin thêm về giây mạng: https://developer.android.com/training/articles/security-config.html#CleartextTrafficPeriled


Cảm ơn rất nhiều! Tôi cũng đang sử dụng url "http". Đã thay đổi nó thành "https" và nó hoạt động. Btw, chỉ cần thay đổi url thành https sẽ không hoạt động, bạn cần chứng chỉ để xử lý điều đó. Máy chủ tôi đang sử dụng hỗ trợ cả hai, vì vậy nó dễ dàng hơn cho tôi. Dù sao, Cảm ơn một Tôn!
Xonshiz 19/07/19

1
vâng ... đối với tôi nó là về dạng cleartext quá .... vì tôi đang sử dụng http.. nó sẽ không có vấn đề nếu tôi sử dụng https.... nhưng trong trường hợp tôi vẫn muốn sử dụng http, tôi thêm trực tiếp android:usesCleartextTraffic="true"vào applicationthẻ trong AndroidManifest.xml. ..và nó làm việc .... cảm ơn vì đề cập về cleartext...
Syamsoul Azrien

Làm cách nào để kích hoạt tính năng này trong Spring boot? Tôi xin lỗi nếu câu hỏi là quá tầm thường nhưng tôi là một người mới bắt đầu và tôi không thể tìm thấy bất kỳ giải pháp trực tuyến
Asma Rahim Ali Jafri

13

làm việc cho tôi sau khi tắt tiện ích chặn quảng cáo trong chrome, lỗi này đôi khi xuất hiện do thứ gì đó chặn http trong trình duyệt

nhập mô tả hình ảnh ở đây


1
đối với tôi nó là uBlock xứ mà bị chặn tải tập tin với 'phân tích' trong nó tên
Marke

9

Nếu bạn đang sử dụng ứng dụng .NET Core, giải pháp này có thể hữu ích!

Hơn nữa, đây có thể không phải là lỗi Angular hoặc yêu cầu khác trong ứng dụng giao diện người dùng của bạn

Đầu tiên, bạn phải thêm gói Microsoft CORS Nuget:

Install-Package Microsoft.AspNetCore.Cors

Sau đó, bạn cần thêm các dịch vụ CORS trong startup.cs của mình. Trong phương thức ConfigureServices của bạn, bạn sẽ có một cái gì đó tương tự như sau:

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

Tiếp theo, thêm phần mềm trung gian CORS vào ứng dụng của bạn. Trong startup.cs của bạn, bạn nên có phương thức Định cấu hình. Bạn cần phải có nó tương tự như sau:

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

Các tùy chọn lambda là một API thông thạo nên bạn có thể thêm / xóa bất kỳ tùy chọn bổ sung nào mà bạn cần. Bạn thực sự có thể sử dụng tùy chọn “AllowAnyOrigin” để chấp nhận bất kỳ miền nào, nhưng tôi thực sự khuyên bạn không nên làm điều này vì nó mở ra các cuộc gọi gốc chéo từ bất kỳ ai. Bạn cũng có thể giới hạn các cuộc gọi gốc chéo đối với Phương thức HTTP của chúng (GET / PUT / POST, v.v.), vì vậy bạn chỉ có thể hiển thị các cuộc gọi GET chéo miền, v.v.


5

Lỗi này xảy ra với tôi trong Firefox chứ không phải Chrome khi đang phát triển cục bộ và hóa ra là do Firefox không tin tưởng chứng chỉ ssl của API cục bộ của tôi (không hợp lệ, nhưng tôi đã thêm nó vào cửa hàng chứng chỉ địa phương của mình, điều này cho phép chrome tin tưởng nó nhưng không ff). Điều hướng trực tiếp đến API và thêm một ngoại lệ trong Firefox đã khắc phục sự cố.


1
Tôi đã xem qua một số câu trả lời CORS và lần lượt từng câu trả lời không đưa ra giải pháp khi sử dụng Firefox. Tôi nhìn vào bài đăng này và nghĩ, "không thể nào thế này được nhưng tôi không có ý tưởng gì nữa" và chắc chắn rằng nó đã hoạt động. Cảm ơn bạn rất nhiều!
Aaron Jordan

@frax, tôi cũng gặp trường hợp tương tự! Cảm ơn! :)
W92

5

Đối với tôi, đó là do JsonSerializerException phía máy chủ.

Đã xảy ra ngoại lệ không được xử lý trong khi thực hiện yêu cầu Newtonsoft.Json.JsonSerializationException: Đã phát hiện vòng lặp tự tham chiếu với kiểu ...

Khách hàng nói:

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

Làm cho kiểu phản hồi đơn giản hơn bằng cách loại bỏ các vòng lặp đã giải quyết được vấn đề.


2

Nếu bạn đang sử dụng Laravel làm Phụ trợ của mình, hãy chỉnh sửa tệp .htaccess của bạn bằng cách chỉ dán mã này, để giải quyết vấn đề CROS trong dự án Angular hoặc IONIC của bạn

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

6
Bạn đừng bao giờ cho phép "*"! Nói chung, bạn biết ai đang nói chuyện với phụ trợ của mình và bạn nên đặt máy chủ của họ một cách rõ ràng.
itmuckel 19/02/18

@itmuckel nhưng nếu bạn đang làm một ứng dụng cho android thì máy chủ lưu trữ đó không được biết đến. Sẽ là mọi thiết bị di động sử dụng dịch vụ của bạn, tôi nói đúng chứ?
Martin

2
chúng tôi cần sử dụng cordova-plugin-advanced-http và @ ionic / native wrapper để thực hiện các cuộc gọi http từ thiết bị thay vì sử dụng lệnh gọi ajax dựa trên trình duyệt. @Martin
user323774

2

Một lỗi tương tự có thể xảy ra khi bạn không cung cấp chứng chỉ máy khách và mã thông báo hợp lệ mà máy chủ của bạn hiểu:

Lỗi:

Phản hồi lỗi Http cho (url không xác định): 0 Lỗi không xác định

Mã ví dụ:

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

}

Lưu ý rằng cả hai MyClientCert& MyTokenđều là chuỗi trống, do đó xảy ra lỗi.
MyClientCert& MyTokencó thể là bất kỳ tên nào mà máy chủ của bạn hiểu được.


tôi sử dụng mã này trong ứng dụng ion của mình. ứng dụng ion của tôi được sử dụng làm chỉ mục trong trang web của tôi. nhưng thủ thuật này không thể giúp tôi. Có vẻ như apis của tôi trong laravel cần cấu hình có thể trong ngnix hoặc laravel hoặc máy chủ docker của tôi ... Tôi đã sử dụng phần mềm trung gian cors cho cors được kích hoạt và nó hoạt động trên cục bộ của tôi với http nhưng khi triển khai trên docker không thể gọi api của tôi bằng https
saber tabatabaee yazdi

khi tôi gọi apis còn lại của mình từ http thì những ứng dụng đó hoạt động nhưng khi gọi https họ không trả lời khách hàng của tôi. và trả về lỗi Loại hỗn hợp. tôi nghĩ rằng có lỗi chứng chỉ hoặc một cái gì đó như cấu hình nginx hoặc .htaccess vì tôi thêm phần mềm trung gian cors cho cors và mọi thứ hoạt động tốt mà không có https. khách hàng của tôi được lưu trữ trên http kết quả cuộc gọi http là ok. nhưng khi khách hàng của tôi lưu trữ trên https và lỗi cuộc gọi https đã xảy ra
saber tabatabaee yazdi

Được rồi, một giải pháp là, truy cập url https: // mà bạn có và nhấp vào biểu tượng ổ khóa bên cạnh https, tải chứng chỉ xuống một tệp, đọc tệp đó qua import / request / fs, sau đó cấp / chuyển cho tệp đó. chuỗi chứng chỉ cho lệnh gọi tới url, sau đó nó sẽ hoạt động.
Manohar Reddy Poreddy

2

Tôi đang sử dụng Tiện ích mở rộng ASP.NET SPA tạo cho tôi một proxy trên các cổng 5000 và 5001 đi qua cổng 4200 của Angular trong quá trình phát triển.

Tôi đã thiết lập CORS chính xác cho cổng https 5001 và mọi thứ đều ổn, nhưng tôi vô tình truy cập vào một dấu trang cũ dành cho cổng 5000. Sau đó, thông báo này đột nhiên xuất hiện. Như những người khác đã nói trong bảng điều khiển có một thông báo lỗi 'preflight'.

Vì vậy, bất kể môi trường của bạn là gì, nếu bạn đang sử dụng CORS, hãy đảm bảo rằng bạn đã chỉ định tất cả các cổng - vì máy chủ và cổng đều quan trọng.


2

Tôi nhận được thông báo chính xác đó bất cứ khi nào yêu cầu của tôi mất hơn 2 phút để hoàn thành. Trình duyệt sẽ ngắt kết nối khỏi yêu cầu, nhưng yêu cầu trên chương trình phụ trợ vẫn tiếp tục cho đến khi hoàn tất. Máy chủ (ASP.NET Web API trong trường hợp của tôi) sẽ không phát hiện ra ngắt kết nối.

Sau cả ngày tìm kiếm, cuối cùng tôi đã tìm ra câu trả lời này , giải thích rằng nếu bạn sử dụng cấu hình proxy , nó có thời gian chờ mặc định là 120 giây (hoặc 2 phút).

Vì vậy, bạn có thể chỉnh sửa cấu hình proxy của mình và đặt nó thành bất kỳ thứ gì bạn cần:

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

Bây giờ, tôi đang sử dụng agentkeepalive để làm cho nó hoạt động với xác thực NTLM và không biết rằng thời gian chờ của agent không liên quan gì đến thời gian chờ của proxy, vì vậy cả hai đều phải được đặt. Tôi đã mất một lúc để nhận ra điều đó, vì vậy đây là một ví dụ:

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

Đối với tôi, đó là vấn đề về trình duyệt, vì các yêu cầu của tôi đều hoạt động tốt trong Postman.

Hóa ra vì một số lý do, Firefox và Chrome đã chặn các yêu cầu chuyển đến cổng 6000, khi tôi thay đổi cổng API ASP.NET thành 4000, lỗi đã chuyển thành lỗi CORS đã biết mà tôi có thể sửa.

Chrome ít nhất đã cho tôi thấy ERR_UNSAFE_PORTđiều đó cho tôi manh mối về những gì có thể xảy ra.


1

Nếu bạn có một tiêu đề cors thích hợp tại chỗ. Mạng công ty của bạn có thể đang loại bỏ tiêu đề cors. Nếu trang web có thể truy cập từ bên ngoài, hãy thử truy cập từ bên ngoài mạng của bạn để xác minh xem mạng có đang gây ra sự cố hay không - một ý tưởng hay bất kể nguyên nhân là gì.


1

Trong lõi asp.net, Nếu bộ điều khiển api của bạn không có chú thích được gọi [AllowAnonymous], hãy thêm nó vào phía trên tên bộ điều khiển của bạn như

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

0

Không quá cũ như các câu hỏi khác, nhưng tôi chỉ gặp khó khăn với điều này trong một ứng dụng Ionic-Laravel và không có gì hoạt động từ đây (và các bài đăng khác), vì vậy tôi đã cài đặt https://github.com/barryvdh/laravel-cors bổ sung trong Laravel và bắt đầu và nó hoạt động khá tốt.


0

Của tôi là do mối quan hệ không hợp lệ trong các mô hình mà tôi đang cố gắng truy vấn. Tìm ra bằng cách gỡ lỗi phản hồi mà nó gặp sự cố tại mối quan hệ.


0

Đối với tôi, đó không phải là một vấn đề góc cạnh. Là một trường kiểu DateTime trong DB có giá trị (0000-00-00) và mô hình của tôi không thể ràng buộc thuộc tính đó chính xác, vì vậy tôi đã thay đổi thành giá trị hợp lệ như (2019-08-12).

Tôi đang sử dụng lõi .net, OData v4 và MySql (đầu nối bưởi EF)


0

Thêm mã này vào tệp kết nối của bạn

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

Nếu đây là một dịch vụ nút, hãy thử các bước được nêu ở đây

Về cơ bản, đó là lỗi Chia sẻ Tài nguyên Nhiều Nguồn gốc (CORS). Thông tin thêm về các lỗi như vậy ở đây .

Sau khi tôi cập nhật dịch vụ nút của mình với các dòng sau, nó đã hoạt động:

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

Lỗi của tôi là tệp quá lớn (lõi dotnet dường như có giới hạn @ ~ 25Mb). Cài đặt

  • maxAllowedContentLength đến 4294967295 (giá trị tối đa của uint) trong web.config
  • trang trí hành động của bộ điều khiển với [DisableRequestSizeLimit]
  • services.Configure (options => {options.MultipartBodyLengthLimit = 4294967295;}); trong Startup.cs

đã giải quyết vấn đề cho tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.