Angularの実際のエラーメッセージではなく、「(不明なURL)のHTTP失敗応答:0不明なエラー」が表示される


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
パベルAgarkov

私は同じ問題に直面しており、これについても質問を作成していました。これが完全なerrオブジェクトです:gist.github.com/GO3LIN/7cffc3b0aa1f24d3e23e28cc907237fc
Mehdi Benmoha

1
またはより良い{"headers":{"normalizedNames":{}、 "lazyUpdate":null、 "headers":{}}、 "status":0、 "statusText": "Unknown Error"、 "url":null、 "ok":false、 "name": "HttpErrorResponse"、 "message": "(不明なURL)のHTTP失敗応答:0不明なエラー"、 "error":{"isTrusted":true}}
Mehdi Benmoha

@PavelAgarkov、それはメッセージのみを記録することではありません。私が受け取ったHttpErrorResponseには、実際のエラーメッセージが含まれていません。これが問題のスクリーンショットです。私がログに記録したエラーには「...不明なエラー...」というメッセージが含まれていることがわかりますが、上のリクエストレスポンスのプレビューを見ると、実際の意味のあるメッセージが表示されています。
grdl 2017年

サービスワーカーを使用していますか?
Mackelito

回答:


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コードで実際のエラーメッセージにアクセスできました。


CORSを有効にするには、次のリンクも役立ちます。docs.microsoft.com
Bobs

11
この行はどこに追加する必要がありますか?
Omid Ataollahi

1
どのように「常に」をexpress.js .use関数に追加しますか?通常、構造は次のとおりです。app.use(function(req、res、next){res.header( "Access-Control-Allow-Origin"、 " localhost:4200");…}); ご覧のように、res.headerでは2つのパラメーター(制御文字列と値)を使用できます。私はさまざまな方法で「常に」追加しようとしましたが、すべて失敗するようです。助言がありますか?
AppDreamer

@grdl、行add_headerを追加する必要がありますか?
sattva_venu

どこにこの行を追加しますか?私はapiにphpを使用しています
Mustafa UYSAL

19

他の誰かが私と同じように迷子になった場合...私の問題は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を再構築し、アプリはエミュレータと電話の両方から通信できるようになりました。

network secの詳細:https : //developer.android.com/training/articles/security-config.html#CleartextTrafficPermitted


トンありがとう!「http」のURLも使用していました。それを「https」に変更して動作しました。ところで、URLをhttpsに変更するだけでは機能しません。これを処理するには証明書が必要です。私が使用していたサーバーは両方をサポートしているので、私にとってはより簡単でした。とにかく、ありがとう!
Xonshiz

1
はい...私にとって、それは私が使用しているので....あまりにもクリアテキストについてではありませんhttp、私が使用している場合...それは何の問題だろうhttps....しかし、私はまだ使用したい場合にはhttp、私が直接追加android:usesCleartextTraffic="true"してapplication、タグAndroidManifest.xml。 ..そして、それは機能しています... ...について言及してくれてありがとうcleartext...
Syamsoul Azrien

Springブートでこれを有効にするにはどうすればよいですか?質問が簡単すぎても申し訳ありませんが、私は初心者であり、オンラインで解決策を見つけることができません
Asma Rahim Ali Jafri

13

Chromeで広告ブロック拡張機能をオフにした後、私のために働いていますが、ブラウザでhttpをブロックする何かが原因でこのエラーが表示されることがあります

ここに画像の説明を入力してください


1
私にとっては、その名前に「analytics」が含まれるファイルのダウンロードをブロックしたのはuBlock Originでした
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();
}

オプションのラムダは流暢な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 2018

@itmuckelしかし、もしあなたがアンドロイドのためのアプリをしているなら、それは知られていません。あなたのサービスを利用するすべてのモバイルでしょうか?
マーティン

2
ブラウザベースのajax呼び出しを使用する代わりに、デバイスからネイティブにhttp呼び出しを行うには、cordova-plugin-advanced-httpおよび@ ionic / nativeラッパーを使用する必要がありました。@Martin
user323774

2

サーバーが理解できる有効なクライアント証明書とトークンを指定しなかった場合も、同様のエラーが発生する可能性があります。

エラー:

(不明な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は、サーバーが理解できる任意の名前にすることができます。


私のイオンアプリでこのコードを使用しています。私のイオンアプリは私のサイトでインデックスとして使用されています。しかし、このトリックは私を助けることができません。laravelの私のAPIは多分ngnixまたはlaravelまたは私のdockerホストで構成が必要なようです... corsミドルウェアを使用してcorsを有効にし、httpでローカルで動作しましたが、
dockerにデプロイする

httpから残りのapiを呼び出すと、これらは機能しましたが、httpsを呼び出すと、クライアントに応答しませんでした。混合型エラーを返します。私はcorsミドルウェアをcorsに追加し、すべてがhttpsなしで正常に機能したため、証明書エラーまたはnginx構成や.htaccessなどの問題があると思います。httpコールでホストされているクライアントhttpの結果は問題ありません。しかし、クライアントのホストがhttpsでhttpsを呼び出すとエラーが発生した
saber tabatabaee yazdi

解決策の1つは、お持ちのhttps:// URLに移動し、httpsの横にあるロックアイコンをクリックして、証明書をファイルにダウンロードし、import / require / fsを介してそのファイルを読み取ってから、それを渡す/渡すことです証明書文字列をURLの呼び出しに追加すると、機能します。
Manohar Reddy Poreddy

2

開発中にAngularのポート4200を通過するポート5000および5001にプロキシを作成するASP.NET SPA拡張機能を使用しています。

CORSでhttpsポート5001を正しく設定していて、すべて問題はありませんでしたが、誤ってポート5000用の古いブックマークに移動しました。その後、突然このメッセージが表示されました。他の人がコンソールで言ったように、「プリフライト」エラーメッセージがありました。

したがって、環境に関係なく、CORSを使用している場合は、ホストとポートの両方が重要であるため、すべてのポートが指定されていることを確認してください。


2

リクエストの完了に2分以上かかったときはいつでも、そのとおりのメッセージが表示されていました。ブラウザはリクエストから切断されますが、バックエンドでのリクエストは完了するまで続行されました。サーバー(私の場合はASP.NET Web API)は切断を検出しません。

丸一日検索した後、私は最終的にこの答えを見つけました、あなたがプロキシ設定を使うなら、デフォルトのタイムアウトは120秒(または2分)ています。

したがって、プロキシ設定を編集して、必要なものに設定できます。

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

今、私はそれをNTLM認証で動作せるために 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(',');
        }
    }
};

2

私にとっては、私の要求はPostmanで問題なく機能していたため、ブラウザーの問題でした。

何らかの理由で6000、ASP.NET APIポートを4000に変更すると、エラーは既知のCORSエラーに変わり、修正できます。

Chromeは少なくとも私ERR_UNSAFE_PORTに何が悪いのかについての手がかりを私に示しました。


1

適切なcorsヘッダーがある場合。企業ネットワークがcorsヘッダーを削除している可能性があります。Webサイトに外部からアクセスできる場合は、ネットワークの外部からWebサイトにアクセスして、ネットワークが問題を引き起こしているかどうかを確認してください。原因に関係なく、適切な方法です。


1

asp.netコアで、APIコントローラーにと呼ばれる注釈がない場合は[AllowAnonymous]、次のようにそれをコントローラー名の上に追加します

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


0

私が照会しようとしたモデルの無効な関係が原因でした。それが関係でクラッシュした応答をデバッグすることによって理解しました。


0

私にとっては、角度の問題ではありませんでした。(0000-00-00)の値を持つDBのDateTimeタイプのフィールドであり、モデルはそのプロパティを正しくバインドできないため、(2019-08-12)のような有効な値に変更しました。

私は.netコア、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の制限があるようです)。設定

  • maxAllowedContentLengthからweb.configの4294967295(uintの最大値)
  • [DisableRequestSizeLimit]でコントローラーアクションを装飾する
  • services.Configure(options => {options.MultipartBodyLengthLimit = 4294967295;}); Startup.cs

私のために問題を解決しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.