Angular 2 - 预检响应具有无效的 HTTP 状态代码 401
Posted
技术标签:
【中文标题】Angular 2 - 预检响应具有无效的 HTTP 状态代码 401【英文标题】:Angular 2 - Response for preflight has invalid HTTP status code 401 【发布时间】:2017-12-31 01:24:18 【问题描述】:我知道这里已经解决了很多相同的问题, 但不幸的是,他们都没有帮助我:-(。 这是我的问题:我尝试从本地主机连接到服务器上的 REST 服务。它适用于 FF REST 插件,但我的应用程序导致以下错误:
选项http://.../my_REST_Service/ 401(未授权) XMLHttpRequest 无法加载 http://.../my_REST_Service/。 预检响应包含无效的 HTTP 状态代码 401我如何尝试获取我想要的数据:
@Injectable()
export class ModelsComponent implements OnInit
private restRoot = 'http://.../my_REST_Service';
private data;
constructor(private http: Http)
ngOnInit()
this.getModels().subscribe(res =>
this.data = res;
console.log(this.data);
);
authHeaders()
let username: string = 'xxxx';
let password: string = 'xxxx';
let token: string = btoa(username + ":" + password);
let headers: Headers = new Headers();
headers.append('Access-Control-Expose-Headers', 'Authorization');
headers.append('Authorization', 'Basic ' + token);
headers.append("Access-Control-Allow-Origin", "http://localhost:4200/");
headers.append("Access-Control-Allow-Methods", "*");
headers.append("Access-Control-Allow-Headers", "Accept,Accept-Charset,Accept-Encoding,Accept-Language,Authorization,Connection,Content-Type,Cookie,DNT,Host,Keep-Alive,Origin,Referer,User-Agent,X-CSRF-Token,X-Requested-With");
headers.append("Access-Control-Allow-Credentials", "true");
return headers;
getModels(): Observable<any>
return this.http.get(this.restRoot,
headers: this.authHeaders(),
withCredentials: true <- from a similar issue
).map(res => res.json());
我的服务器是这样配置的:
Header set Access-Control-Allow-Origin "http://localhost:4200"
Header set Access-Control-Allow-Headers "Accept,Accept-Charset,Accept-Encoding,Accept-Language,Authorization,Connection,Content-Type,Cookie,DNT,Host,Keep-Alive,Origin,Referer,User-Agent,X-CSRF-Token,X-Requested-With"
Header set Access-Control-Allow-Methods "*"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Expose-Headers "Authorization" <- from a similar issue
我知道还有其他相同/类似的已解决问题。但我仍然不知道该做什么或如何去做。 如果有人可以帮助我编写代码,我将不胜感激!
【问题讨论】:
不要在您的请求中放置访问控制标头!它们是响应标头! 【参考方案1】:在服务器端,如果使用 Node.js,您可以考虑授权所有 OPTIONS 请求,这样浏览器就不需要验证来检查服务器/REST API 上授权了哪些方法。
考虑如下代码:
if (req.method === 'OPTIONS')
res.status(200).end();
else
next();
【讨论】:
【参考方案2】:浏览器在执行HttpGet
之前执行OPTIONS
请求,您需要添加与HttpGet
具有相同路由的端点,将其设为HttpOptions
请求,从该端点删除身份验证并返回200 OK
来自它,这应该可以解决您的问题。
【讨论】:
不是 Angular 正在执行 OPTIONS 请求,而是浏览器。 感谢您的回答,但我不确定我是否正确。我是否必须在我的 Angular 代码中发出没有身份验证的 HttpOptions 请求,还是必须从 REST 端点中删除身份验证?问题是使用的 REST-API 默认情况下需要对有效用户进行身份验证,并且无法从中删除身份验证。还是我完全误解了你的答案? 您需要为 HttpOptions 创建一个 REST 端点。它将与您的其他端点完全相同,只有 http 动词是HttpOptions
。此端点将仅返回状态 200 Ok 响应。此端点应允许匿名身份验证,因为选项请求不包含授权。
好吧,那不可能。我使用具有多个端点的修复 REST 服务。也许我找到了一种完全关闭授权的方法。【参考方案3】:
“我的服务器是这样配置的”——这几乎是无关紧要的。查看报错信息:“Response for preflight has invalid HTTP status code 401”
它没有说明您在 Access-Control-Allow-Thing 中提到的任何事情。
浏览器正在发出 OPTIONS 请求,询问是否允许跨源请求。 响应显示“您的用户名和密码错误”。由于浏览器没有收到跨域请求的权限:没有发送用户名和密码。
您需要在您的服务器上找到执行授权的代码,并从该测试中排除 OPTIONS 请求。任何人都应该能够提出 OPTIONS 请求,而不仅仅是拥有用户名和密码的人。
【讨论】:
您认为在某些情况下排除 OPTIONS 请求可能是安全问题吗? @KyleVassella — 仅当您对它们做出不恰当的响应时(例如,将它们视为 POST 请求并将数据存储在数据库中)。以上是关于Angular 2 - 预检响应具有无效的 HTTP 状态代码 401的主要内容,如果未能解决你的问题,请参考以下文章
预检响应在 Angular Js1 和 Webapi 2 上具有无效的 HTTP 状态代码 405
Angular 5:预检响应具有无效的 HTTP 状态代码 403
Angular $http:预检响应具有无效的 HTTP 状态代码 403