我正在使用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工具中看到的实际响应消息?
答案 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)
答案 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)) );
}
}
请注意,MyClientCert
和MyToken
都是空字符串,因此会出现错误。
MyClientCert
和MyToken
可以是服务器可以理解的任何名称。
答案 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 作为后端,请遵循以下步骤
在您的后端应用中安装 cors
npm 安装 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
}));
答案 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)。您可以根据需要进一步限制它。
<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)。设置
为我解决了这个问题。
答案 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补码并开始了效果很好。