Angular의 실제 오류 메시지 대신 "(unknown url) : 0 Unknown Error"에 대한 HTTP 실패 응답이 표시됩니다.


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콘솔에 일반 메시지가 표시된다는 것입니다. 한편 크롬에서 실패한 요청을 살펴보면 응답 상태가 422임을 알 수 있으며 "미리보기"탭에서 실패 원인을 설명하는 실제 메시지를 볼 수 있습니다.

크롬 개발 도구에서 볼 수있는 실제 응답 메시지에 어떻게 액세스합니까?

다음은 문제를 보여주는 스크린 샷입니다. 여기에 이미지 설명 입력


전체 로그온을 시도 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

서비스 워커를 사용하고 있습니까?
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/en-us/aspnet/web-api/overview/security/…
Bobs

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

이 줄을 어디에 추가합니까? 내 API에 PHP를 사용합니다
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"URL을 사용하고 있었다. "https"로 변경하고 작동했습니다. Btw, URL을 https로 변경하는 것은 작동하지 않으며이를 처리하려면 인증서가 필요합니다. 내가 사용하고 있던 서버는 둘 다 지원하기 때문에 더 쉬웠습니다. 어쨌든 감사합니다!
Xonshiz

1
예 ... 저에게도 일반 텍스트에 관한 것입니다 .... 사용하고 있기 때문에 http.. 사용하면 문제가되지 않을 것입니다 https. ....하지만 여전히 사용하고 싶은 경우 에는 태그를 http직접 추가 합니다. .. 그리고 그것에 대해 언급을위한 .... 덕분에 일하고있어 ...android:usesCleartextTraffic="true"applicationAndroidManifest.xmlcleartext
Syamsoul Azrien

스프링 부트에서 어떻게 활성화 할 수 있습니까? 나는 질문이 너무 사소한 경우 죄송하지만 초보자와 나는 온라인 어떤 해결책을 찾을 수 없습니다
아스마 라힘 알리 Jafri

13

크롬에서 광고 차단 확장 프로그램을 끈 후 나를 위해 일하면 브라우저에서 http를 차단하는 것이 있기 때문에이 오류가 나타납니다.

여기에 이미지 설명 입력


1
나를 위해 그것의 이름으로 '분석'에 파일을 다운로드 차단 된 uBlock 기원했다
마르크

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 인증서를 신뢰하지 않기 때문에 발생하는 것으로 나타났습니다 (유효하지 않지만 로컬 인증서 저장소에 추가했습니다. 크롬은 그것을 신뢰하지만 ff는 아닙니다). API로 직접 이동하고 Firefox에서 예외를 추가하면 문제가 해결되었습니다.


1
여러 CORS 답변을 살펴 보았고 Firefox를 사용할 때 하나씩 해결책을 제공하지 못했습니다. 나는이 포스트를보고 "이건 아니에요.하지만 도대체 무슨 일인지 생각이 나지 않습니다"라고 생각했고 충분히 효과가있었습니다. 정말 고맙습니다!
Aaron Jordan

@frax, 나는 정확히 같은 사건을 가졌습니다! 감사! :)
W92

5

나를 위해 그것은 서버 측 JsonSerializerException으로 인해 발생했습니다.

요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. Newtonsoft.Json.JsonSerializationException : Self referencing loop detected with type ...

클라이언트는 다음과 같이 말했습니다.

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이지만 안드로이드 호스트 용 앱을 사용하는 경우 알려지지 않았습니다. 당신의 서비스를 소비하는 모든 모바일이 될까요?
Martin

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

}

MyClientCert& 둘 다 MyToken빈 문자열이므로 오류가 발생합니다.
MyClientCert& MyToken는 서버가 이해하는 모든 이름이 될 수 있습니다.


이 코드를 내 이온 앱에서 사용합니다. 내 사이트에서 색인으로 사용되는 내 이온 앱. 그러나이 트릭은 나를 도울 수 없습니다. laravel의 내 API는 ngnix 또는 laravel 또는 내 도커 호스트에서 구성이 필요한 것 같습니다. cors를 활성화하기 위해 cors 미들웨어를 사용했고 http를 사용하여 내 로컬에서 작동했지만 도커에 배포 할 때 https로 내 API를 호출 할 수 없습니다
saber tabatabaee yazdi

http에서 내 나머지 API를 호출하면 작동했지만 https를 호출하면 내 클라이언트에 응답하지 않았습니다. 혼합 유형 오류를 반환합니다. cors에 대한 cors 미들웨어를 추가하고 모든 것이 https없이 잘 작동하기 때문에 인증서 오류 또는 nginx 구성 또는 .htaccess와 같은 것이 있다고 생각합니다. http call http 결과에서 호스팅되는 내 클라이언트는 괜찮습니다. 하지만 내 클라이언트 호스트에서 https 및 호출 https 오류가 발생했을 때
saber tabatabaee yazdi

한 가지 해결책은 가지고있는 https : // url로 이동하여 https 옆에있는 잠금 아이콘을 클릭하고 인증서를 파일로 다운로드 한 다음 import / require / fs를 통해 해당 파일을 읽은 다음 제공 / 전달하는 것입니다. URL에 대한 호출에 대한 인증서 문자열을 사용하면 작동합니다.
Manohar Reddy Poreddy

2

개발 중에 Angular의 포트 4200을 통과하는 포트 5000 및 5001에 프록시를 만드는 ASP.NET SPA Extensions를 사용하고 있습니다.

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에서 잘 작동했기 때문에 나에게는 브라우저 문제였습니다.

어떤 이유로 Firefox와 Chrome이 포트로가는 요청을 차단 6000하고 ASP.NET API 포트를로 4000변경하면 오류가 수정 가능한 알려진 CORS 오류로 변경된 것으로 나타났습니다.

Chrome은 적어도 나 ERR_UNSAFE_PORT에게 무엇이 잘못 될 수 있는지에 대한 단서를 주었다는 것을 보여 주었습니다.


1

적절한 cors 헤더가있는 경우. 회사 네트워크에서 cors 헤더를 제거 할 수 있습니다. 웹 사이트가 외부에서 액세스 할 수있는 경우 네트워크 외부에서 액세스하여 네트워크가 문제를 일으키는 지 확인하십시오. 원인에 관계없이 좋은 생각입니다.


1

asp.net core에서 api 컨트롤러에라는 주석이 없으면 [AllowAnonymous]다음과 같이 컨트롤러 이름 위에 추가하십시오.

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


0

내 것은 내가 쿼리하려는 모델의 잘못된 관계로 인해 발생했습니다. 관계에서 충돌 한 응답을 디버깅하여 알아 냈습니다.


0

저에게는 각도 문제가 아니 었습니다. DB에서 값이 (0000-00-00) 인 DateTime 유형의 필드 였고 내 모델이 해당 속성을 올바르게 바인딩 할 수 없으므로 (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 (Cross-Origin Resource Sharing) 오류입니다. 이러한 오류에 대한 자세한 내용은 여기를 참조하십시오 .

다음 줄로 노드 서비스를 업데이트하면 작동했습니다.

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.MultipartBodyLengthLimit = 4294967295;}); Startup.cs에서

나를 위해 문제를 해결했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.