我收到“针对(未知URL):0未知错误的Http故障响应”,而不是Angular中的实际错误消息


121

我正在使用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
Pavel Agarkov

我也面临同样的问题,也将为此创建一个问题,这是完整的err对象:gist.github.com/GO3LIN/7cffc3b0aa1f24d3e23e28cc907237fc
Mehdi Benmoha

1
或更好的{“ headers”:{“ normalizedNames”:{},“ lazyUpdate”:null,“ headers”:{}},“ status”:0,“ statusText”:“未知错误”,“ url”:null, “ ok”:false,“ name”:“ HttpErrorResponse”,“ message”:“ Http失败响应(未知url):0 Unknown Error”,“ error”:{“ isTrusted”:true}}
Mehdi Benmoha

@PavelAgarkov,这与仅记录消息无关。我reveive的HttpErrorResponse不包含实际的错误消息。这是问题的屏幕截图。您可以在那里看到我记录的错误消息中显示“ ...未知错误...”,但是当您查看上方的请求响应预览时,可以看到实际的有意义的消息。
grdl

您正在使用服务人员吗?
Mackelito

Answers:


96

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

所请求的资源上没有“ Access-Control-Allow-Origin”标头。因此,不允许访问源“ http:// localhost:4200 ”。该响应具有HTTP状态代码422。

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

但是,此指令仅在响应代码为20X或30X时才添加标头。在错误响应上,标头丢失。always无论响应代码如何,我都需要使用参数来确保添加了标头:

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

一旦正确配置了后端,就可以使用Angular代码访问实际的错误消息。



11
该行应添加到哪里?
Omid Ataollahi

1
如何将“始终”添加到express.js .use函数?通常,结构为:app.use(function(req,res,next){res.header(“ Access-Control-Allow-Origin”,“ localhost:4200”);…}); 如您所见,res.header允许两个参数...一个控制字符串和一个值。我试图以各种方式添加“始终”,但是它们似乎都失败了。有什么建议?
AppDreamer

@grdl,应在哪里添加add_header行?
sattva_venu

在哪里添加这一行?我将php用于我的api
Mustafa UYSAL

19

万一其他人像我一样迷路了……我的问题不是由于CORS(我完全控制了服务器,CORS配置正确!)。

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

添加网络安全配置

项目中的新文件: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将不起作用,您需要使用证书来处理。我使用的服务器都支持,因此对我来说更容易。无论如何,谢谢吨!
Xonshiz

1
是的...对我来说也是关于明文的....因为我使用的是http..如果我使用..也没问题,https但是如果我仍然想使用http,我可以直接android:usesCleartextTraffic="true"application中添加标记AndroidManifest.xml。 ..和它的工作....谢谢你关于提cleartext...
Syamsoul Azrien

如何在Spring Boot中启用此功能?我很抱歉,如果这个问题太琐碎,但是我是一个初学者,我在网上找不到任何解决方案
Asma Rahim Ali Jafri

13

在chrome中关闭广告屏蔽扩展名后为我工作,有时会出现此错误,因为某些内容会阻止浏览器中的http

在此处输入图片说明


1
对我来说,是uBlock Origin阻止了下载名称为“ analytics”的文件
marke

9

如果您使用的是.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();
}

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


5

对于我,此错误是在Firefox中发生的,但在本地开发时不是Chrome,这是由于Firefox不信任本地API的ssl证书(无效,但已将其添加到我的本地证书存储中导致的)导致的chrome信任它,但不信任ff)。直接导航到API并在Firefox中添加例外解决了该问题。


1
我经历了几个 CORS答案,一个接一个地使用Firefox时,每个答案都没有提供解决方案。我看了一下这篇文章,心想:“这不可能,但是我不知道到底是怎么回事”,而且确实可以奏效。非常感谢!
亚伦·乔丹

@frax,我的情况完全一样!谢谢!:)
W92

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, …}

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


2

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

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

6
您永远不要允许“ *”!通常,您知道谁正在与您的后端通信,因此您应该明确设置他们的主机。
itmuckel

@itmuckel,但是如果您正在为Android做一个应用程序,那么它的主机是未知的。是会消耗您服务的所有手机吗?
马丁

2
我们需要使用cordova-plugin-advanced-http和@ ionic / native包装器从设备本地发出http调用,而不是使用基于浏览器的ajax调用。@Martin
user323774 '18

2

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

错误:

针对(未知网址)的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可以是您的服​​务器可以理解的任何名称。


我在离子应用程序中使用此代码。我的离子应用程序在我的网站中用作索引。但这招不能帮助我。似乎我在laravel中的api需要在ngnix或laravel或我的docker主机中进行配置...我使用cors中间件启用了cors,它在我的本地服务器上可以通过http工作,但是当部署在docker上时,无法使用https调用我的api
saber tabatabaee yazdi

当我从http调用我的其他api时,这些方法有效,但是当调用https时,它们没有响应我的客户。并返回混合类型错误。我认为这里存在证书错误或类似nginx配置或.htaccess的错误,因为我为cors添加了cors中间件,并且在没有https的情况下一切正常。我通过http调用http托管的客户端结果正常。但是当我的客户在https上托管并致电https时,发生了错误
saber tabatabaee yazdi

好的,一种解决方法是,转到您拥有的https:// URL,然后单击https旁边的锁图标,将证书下载到文件中,通过import / require / fs读取该文件,然后提供/传递该证书证书字符串调用该URL,然后它将起作用。
Manohar Reddy Poreddy,

2

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

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

因此,不管您的环境如何,如果您使用的是CORS,请确保指定了所有端口-主机和端口都至关重要。


2

每当我的请求花了2分钟以上的时间,我就会收到确切的消息。浏览器将断开与请求的连接,但后端的请求将继续进行直到完成为止。服务器(在我的情况下为ASP.NET Web API)无法检测到断开连接。

经过一整天的搜索,我终于找到了这个答案,并解释说,如果您使用代理配置,则默认超时为120秒(或2分钟)。

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

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

现在,我正在使用agentkeepalive 使其与NTLM身份验证一起使用,并且不知道代理的超时与代理的超时无关,因此必须同时设置两者。我花了一段时间才意识到这一点,所以这里有一个例子:

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

对我来说,这是一个浏览器问题,因为我的请求在Postman中工作正常。

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

Chrome至少向我展示了ERR_UNSAFE_PORT这可能给我带来了什么错误的线索。


1

如果您有正确的cors标头。您的公司网络可能正在剥夺cors标头。如果可以从外部访问该网站,请尝试从网络外部访问该网站,以验证该网络是否是造成问题的一个好主意,无论原因如何。


1

在asp.net核心中,如果您的api控制器没有调用[AllowAnonymous],则将其添加到您的控制器名称上方,例如

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


0

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


0

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

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


0

在连接文件中添加此代码

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

如果这是节点服务,请尝试此处概述的步骤

基本上,这是跨域资源共享(CORS)错误。有关此类错误的更多信息,请参见此处

使用以下几行更新节点服务后,它便可以工作:

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

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

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

为我解决了问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.