我收到“(未知 url)的 Http 失败响应:0 未知错误”而不是 Angular 中的实际错误消息

Posted

技术标签:

【中文标题】我收到“(未知 url)的 Http 失败响应:0 未知错误”而不是 Angular 中的实际错误消息【英文标题】:I get "Http failure response for (unknown url): 0 Unknown Error" instead of actual error message in Angular 【发布时间】:2018-04-21 04:40:41 【问题描述】:

我正在使用 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 开发工具中看到的实际响应消息?

这是一个演示问题的屏幕截图:

【问题讨论】:

尝试记录整个 err 对象 - 不仅是 message 我遇到了同样的问题,也打算为此创建一个问题,这是完整的错误对象:gist.github.com/GO3LIN/7cffc3b0aa1f24d3e23e28cc907237fc 或者更好 "headers":"normalizedNames":,"lazyUpdate":null,"headers":,"status":0,"statusText":"Unknown Error ","url":null,"ok":false,"name":"HttpErrorResponse","message":"(未知 url)的 Http 失败响应:0 未知错误","error":"isTrusted":真的 @PavelAgarkov,这不仅仅是记录消息。我收到的 HttpErrorResponse 不包含实际的错误消息。这是问题的screenshot。您可以在那里看到我记录的错误消息“...未知错误...”,但是当您查看上面的请求响应预览时,您可以看到实际的、有意义的消息。 你在使用 service worker 吗? 【参考方案1】:

问题与CORS 有关。我注意到 Chrome 控制台中还有另一个错误:

请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'http://localhost:4200' 不允许访问。响应的 HTTP 状态代码为 422。`

这意味着来自后端服务器的响应缺少 Access-Control-Allow-Origin 标头,即使后端 nginx 已配置为使用 add_header directive 将这些标头添加到响应中。

但是,此指令仅在响应代码为 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/… 这行应该加在哪里? 如何将“always”添加到 express.js .use 函数中?通常的结构是: app.use(function(req, res, next) res.header("Access-Control-Allow-Origin", "localhost:4200"); ... ); 如你所见 res.header允许两个参数...一个控制字符串和一个值。我尝试以各种方式添加“始终”,但它们似乎都失败了。有什么建议吗? @grdl,add_header 应该加在哪里? 如果您使用 express,您必须将其作为中间件添加到 express 服务器。更多信息在这里enable-cors.org/server_expressjs.html【参考方案2】:

万一其他人最终像我一样迷失了......我的问题不是由于 CORS(我完全控制了服务器并且 CORS 配置正确!)。

我的问题是因为我使用的是 android 平台级别 28,它默认禁用明文网络通信,并且我正在尝试开发指向我笔记本电脑 IP(运行 API 服务器)的应用程序. API 基本 URL 类似于 http://[LAPTOP_IP]:8081。由于不是 https,android webview 完全阻止了手机/模拟器和我笔记本电脑上的服务器之间的网络传输。为了解决这个问题:

添加网络安全配置

项目中的新文件: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

【讨论】:

非常感谢!我还使用了“http”网址。将其更改为“https”并且有效。顺便说一句,只是将 url 更改为 https 是行不通的,你需要一个证书来处理它。我使用的服务器支持两者,所以对我来说更容易。无论如何,非常感谢! 是的......对我来说,这也是关于明文的......因为我正在使用http..如果我使用https..不会有问题......但是在如果我仍然想使用http,我直接在application 标签中添加android:usesCleartextTraffic="true" AndroidManifest.xml ...它正在工作....感谢提及cleartext... 如何在 Spring Boot 中启用此功能?如果问题太琐碎,我很抱歉,但我是初学者,我在网上找不到任何解决方案 那是聪明的伙伴,这也解决了我的问题,谢谢。 :)【参考方案3】:

在 chrome 中关闭广告阻止扩展后为我工作,有时会出现此错误,因为在浏览器中阻止 http

【讨论】:

对我来说是 uBlock Origin 阻止下载名称中带有“分析”的文件【参考方案4】:

如果您使用的是 .NET Core 应用程序,此解决方案可能会有所帮助!

此外,这可能不是前端应用程序中的 Angular 或其他请求错误

首先,您必须添加 Microsoft CORS Nuget 包:

Install-Package Microsoft.AspNetCore.Cors

然后您需要在您的 startup.cs 中添加 CORS 服务。在您的 ConfigureServices 方法中,您应该具有类似于以下内容的内容:

public void ConfigureServices(IServiceCollection services)

    services.AddCors();

接下来,将 CORS 中间件添加到您的应用中。在您的 startup.cs 中,您应该有一个 Configure 方法。你需要有类似这样的:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
ILoggerFactory loggerFactory)

    app.UseCors( options => 
    options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
    app.UseMvc();

options lambda 是一个流畅的 API,因此您可以添加/删除您需要的任何额外选项。您实际上可以使用“AllowAnyOrigin”选项来接受任何域,但我强烈建议您不要这样做,因为它会打开来自任何人的跨域调用。您还可以限制对其 HTTP 方法(GET/PUT/POST 等)的跨源调用,因此您只能跨域等公开 GET 调用。

【讨论】:

【参考方案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, …

通过消除循环使响应类型更简单解决了问题。

【讨论】:

【参考方案6】:

我在本地开发时在 Firefox 而不是 Chrome 中发生了这个错误,结果是 Firefox 不信任我的本地 API 的 ssl 证书(这是无效的,但我有将它添加到我的本地证书存储中,这让 chrome 信任它但不是 ff)。直接导航到 API 并在 Firefox 中添加异常解决了该问题。

【讨论】:

我已经浏览了 几个 CORS 答案,并且在使用 Firefox 时一个接一个地没有提供解决方案。我看着这篇文章并想,“不可能是这样,但我不知道到底是什么”,果然它奏效了。非常感谢! @frax,我的情况完全一样!谢谢! :)【参考方案7】:

如果您没有提供服务器理解的有效客户端证书和令牌,可能会发生类似错误:

错误:

(未知 url)的 Http 失败响应: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)) );
  


请注意,MyClientCertMyToken 都是空字符串,因此会出现错误。MyClientCertMyToken 可以是您的服​​务器可以理解的任何名称。

【讨论】:

我在我的 ionic 应用程序中使用此代码。我的 ionic 应用程序在我的网站中用作索引。但是这个技巧帮不了我。似乎我在 laravel 中的 api 需要配置可能在 ngnix 或 laravel 或我的 docker 主机中......我使用 cors 中间件启用了 cors,它在我的本地使用 http 但部署在 docker 上时无法使用 https 调用我的 api 当我从 http 调用我的 rest api 时,那些工作正常,但是当调用 https 时,他们没有响应我的客户。并返回混合类型错误。我认为存在证书错误或 nginx 配置或 .htaccess 之类的东西,因为我为 cors 添加了 cors 中间件,并且在没有 https 的情况下一切正常。我的客户端托管在 http 调用 http 结果上还可以。但是当我的客户端主机在 https 上并调用 https 时发生错误 好的,一种解决方案是,转到您拥有的 https:// url,然后单击 https 旁边的锁定图标,将证书下载到文件中,通过 import/require 读取该文件/fs,然后将该证书字符串提供/传递给对 url 的调用,然后它将起作用。【参考方案8】:

只要我的请求需要超过 2 分钟才能完成,我就会收到确切的消息。浏览器会断开与请求的连接,但后端的请求会一直持续到完成。服务器(在我的例子中为 ASP.NET Web API)不会检测到断开连接。

经过一整天的搜索,我终于找到了this answer,解释说如果你使用proxy config,它的默认超时时间是120秒(或2分钟)。

因此,您可以编辑代理配置并将其设置为您需要的任何内容:


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

现在我用agentkeepalive到make it work with NTLM authentication,不知道agent的timeout和proxy的timeout没有关系,所以两个都要设置。我花了一段时间才意识到这一点,所以这里有一个例子:

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(',');
        
    
;

【讨论】:

【参考方案9】:

我正在使用 ASP.NET SPA 扩展,它在端口 5000 和 5001 上为我创建了一个代理,在开发过程中通过 Angular 的端口 4200。

我已经为 https 端口 5001 正确设置了 CORS,一切都很好,但我无意中转到了一个用于端口 5000 的旧书签。然后突然出现了这条消息。正如其他人在控制台中所说,有一条“预检”错误消息。

因此,无论您的环境如何,如果您使用 CORS,请确保您已指定所有端口 - 因为主机和端口都很重要。

【讨论】:

【参考方案10】:

对我来说这是一个浏览器问题,因为我的请求在 Postman 中运行良好。

事实证明,由于某种原因,Firefox 和 Chrome 阻止了前往端口 6000 的请求,一旦我将 ASP.NET API 端口更改为 4000,该错误就变成了我可以修复的已知 CORS 错误。

Chrome 至少向我展示了 ERR_UNSAFE_PORT,这让我知道了可能出现的问题。

【讨论】:

【参考方案11】:

如果您使用 Laravel 作为后端,则只需粘贴此代码即可编辑 .htaccess 文件,以解决 Angular 或 IONIC 项目中的问题 CROS

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

【讨论】:

你永远不应该允许“*”!一般来说,您知道谁在与您的后端交谈,您应该明确设置他们的主机。 @itmuckel 但如果您正在为 android 开发应用程序,则主机未知。将是每台使用您的服务的手机,对吗? 我们需要使用cordova-plugin-advanced-http 和@ionic/native 包装器来从设备本地调用http,而不是使用基于浏览器的ajax 调用。 @马丁【参考方案12】:

如果您有适当的 cors 标头。您的公司网络可能正在剥离 cors 标头。如果该网站可以从外部访问,请尝试从您的网络外部访问它,以验证网络是否导致了问题 - 无论原因如何,这都是一个好主意。

【讨论】:

【参考方案13】:

如果这是一个节点服务,请尝试here列出的步骤

基本上,这是一个跨域资源共享 (CORS) 错误。有关此类错误的更多信息here。

一旦我用以下几行更新了我的节点服务,它就起作用了:

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

【讨论】:

【参考方案14】:

如果您使用 nodejs 作为后端,请遵循以下步骤

    在您的后端应用中安装 cors

    npm install cors

    添加此代码

     const cors = require('cors');
     const express = require('express');
     const expressApp = express();
     expressApp.use(cors(
         origin: ['http://localhost:4200'],
         "methods": "GET,PUT,POST",
         "preflightContinue": false,
         "optionsSuccessStatus": 204,
         credentials: true
     ));
    

【讨论】:

【参考方案15】:

不像其他问题那么古老,但我只是在 Ionic-Laravel 应用程序中遇到了这个问题,这里(和其他帖子)没有任何效果,所以我在 Laravel 中安装了https://github.com/barryvdh/laravel-cors 补充并开始运行,它运行良好好吧。

【讨论】:

【参考方案16】:

我的问题是由我尝试查询的模型中的无效关系引起的。通过调试它在关系中崩溃的响应来弄清楚。

【讨论】:

【参考方案17】:

对我来说,这不是角度问题。是数据库中 DateTime 类型的字段,其值为 (0000-00-00),我的模型无法正确绑定该属性,因此我更改为有效值,例如 (2019-08-12)。

我正在使用 .net core、OData v4 和 mysql(EF pomelo 连接器)

【讨论】:

【参考方案18】:

在您的连接文件中添加此代码

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

【讨论】:

【参考方案19】:

在 asp.net 核心中,如果您的 api 控制器没有名为 [AllowAnonymous] 的注释,请将其添加到您的控制器名称上方,如

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

【讨论】:

这将禁用整个控制器的身份验证。【参考方案20】:

服务端必须使用--port ng serve --open --port 4200

    export class DatabaseService 
  baseUrl: String = "http://localhost:8080/";
  constructor(private http: HttpClient)  


  saveTutorial(response) 
    var fullUrl = this.baseUrl + "api/tutorials";
   
    return this.http.post(fullUrl,response);
  

【讨论】:

【参考方案21】:

我的错误是文件太大(dotnet core 似乎有一个限制@~25Mb)。设置

web.config 中的 maxAllowedContentLength 为 4294967295(uint 的最大值) 使用 [DisableRequestSizeLimit] 修饰控制器操作 services.Configure(options => options.MultipartBodyLengthLimit = 4294967295; );在 Startup.cs 中

为我解决了问题。

【讨论】:

以上是关于我收到“(未知 url)的 Http 失败响应:0 未知错误”而不是 Angular 中的实际错误消息的主要内容,如果未能解决你的问题,请参考以下文章

devextreme-datagrid update:message:“(未知URL)的Http失败响应:0未知错误”

我收到粘贴板内容更改通知后收到很多崩溃

为啥我收到的 jwt 格式错误?

我收到“错误:React.Children.only 预计会收到一个 React 元素子项。”带有 TouchableWithoutFeedback

当我没有收到手动运行代码时,在 Python for 循环中收到 KeyError

尝试控制台时收到 401~UNAUTHORIZED。记录我从 socket.io 收到的消息