我得到“(未知网址)的Http失败响应:0未知错误”而不是Angular

时间:2017-11-08 13:10:28

标签: angular typescript

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

以下是展示问题的屏幕截图: enter image description here

22 个答案:

答案 0 :(得分:67)

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

  

请求的资源上没有“Access-Control-Allow-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代码中的实际错误消息。

答案 1 :(得分:6)

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

enter image description here

答案 2 :(得分:3)

对我而言,它是由服务器端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, …}

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

答案 3 :(得分:3)

我在Firefox中发生了这个错误,但在本地开发时却没有Chrome,而且原因是Firefox不信任我的本地API的 ssl证书(这是无效的) ,但我把它添加到我当地的证书商店,让Chrome信任它,但不是ff)。直接导航到API并在Firefox中添加例外修复了这个问题。

答案 4 :(得分:2)

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

事实证明,由于某些原因,Firefox和Chrome阻止了将请求发送到端口6000的请求,一旦我将ASP.NET API端口更改为4000,该错误就更改为一个已知的CORS错误,可以解决。

Chrome至少向我展示了ERR_UNSAFE_PORT,这为我提供了可能出问题的线索。

答案 5 :(得分: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可以是服务器可以理解的任何名称。

答案 6 :(得分:2)

如果U家伙在下面使用.net核心应用程序,则可能对您有所帮助!

MoreOver这不是FrontEnd应用程序中的 Angular或其他请求错误

首先,您必须从Nuget添加Microsoft CORS软件包。如果您的人未添加到您的应用程序中,请遵循安装命令。

Install-Package Microsoft.AspNetCore.Cors

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

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调用。

谢谢 sathish(sat)

答案 7 :(得分:1)

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

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

答案 8 :(得分:1)

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

  1. 在您的后端应用中安装 cors

    npm 安装 cors

  2. 添加此代码

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

答案 9 :(得分:1)

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

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

答案 10 :(得分:1)

如果这是节点服务,请尝试概述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();
  });

答案 11 :(得分:1)

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

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

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

答案 12 :(得分:0)

万一其他人像我一样迷路了……我的问题不是由于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

答案 13 :(得分:0)

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

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

为我解决了这个问题。

答案 14 :(得分:0)

在这里查找所有注释后,我遇到了同样的错误,没有任何帮助。最终,我的节点服务器没有运行。

答案 15 :(得分:0)

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

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

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

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

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

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

答案 16 :(得分:0)

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

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

答案 17 :(得分: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");

答案 18 :(得分:0)

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

答案 19 :(得分:0)

我的原因是我尝试查询的模型中的无效关系引起的。通过调试响应找出它在关系上崩溃了。

答案 20 :(得分:0)

服务服务器时必须使用--port ng服务-打开-端口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 :(得分:0)

它不像其他问题那么古老,但是我只是在Ionic-Laravel应用程序中苦苦挣扎,而这里(以及其他帖子)都没有任何效果,因此我在Laravel中安装了https://github.com/barryvdh/laravel-cors补码并开始了效果很好。