我是angular2的新手。我正在尝试登录我的Django服务器,这是一个来自localhost的生产服务器,我正在编写我的前端代码。另外,我是端口转发到我的生产服务器。 我一直在收到CORS问题。 这是我在我的控制台中出现的错误:
XMLHttpRequest无法加载https://www.smartkart.ca/api/user/login/。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许原点“http://127.0.0.1:8000”访问。
我已经写了我的HTTpService并且已经阅读了几乎所有的博客,以找出解决方案,但没有运气。我相信我需要使用withCredentials:true属性。我阅读了一些博客并修改了我的代码以支持withCredentials,但没有运气。
这是我的代码段:
import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import 'rxjs/add/operator/map';
import {Headers} from 'angular2/http';
import {BaseRequestOptions, RequestOptions} from 'angular2/http';
@Injectable()
export class HTTPService {
constructor(private _http: Http) {
}
baseUrl: String = "https://www.smartkart.ca/";
getStoreList() {
return this._http.get(this.baseUrl + 'api/current/store/')
.map(res => res.json());
};
getCookie(name) {
let value = "; " + document.cookie;
let parts = value.split("; " + name + "=");
if (parts.length == 2)
return parts.pop().split(";").shift();
};
login(){
// var request = new XMLHttpRequest();
// var params = JSON.stringify({'email': 'karan@smartkart.ca', 'password': 'k0ttawa#1234'});
// request.open('POST', this.baseUrl+ "api/user/login/", true);
// request.onreadystatechange = function() {if (request.readyState==4) alert("It worked!");};
// request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// request.setRequestHeader("Content-length", params.length.toString());
// request.setRequestHeader("Connection", "close");
// request.send(params);
var data = JSON.stringify({'email': 'test@smartkart.ca', 'password': 'blahblah'});
var params = data;
var headers = new Headers ();
headers.append('Accept', 'application/json');
headers.append('Authorization', 'Basic ' + btoa('karan@smartkart.ca:k0ttawa#1234'));
headers.append("Content-type", "application/x-www-form-urlencoded, application/json");
// headers.append("Content-length", params.length.toString());
// headers.append('Access-Control-Allow-Origin', '*');
// headers.append('Access-Control-Request-Headers', 'x-requested-with');
// headers.append('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// headers.append('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// headers.append('Access-Control-Allow-Credentials', 'true');
// headers.append('Content-Type', 'pplication/x-www-form-urlencoded');
// headers.append('X-CSRFToken', this.getCookie('csrftoken'));
return this._http.post(this.baseUrl+ "api/user/login/", params,
{
headers: headers
}
).map(res => res.json())
};
}
这是我在浏览器的网络标签中看到的内容
现在,如果我拿走了授权标题,我确实登录了,我收回了csrf令牌,但由于CORS问题,我永远无法从服务器得到任何响应。这是一个快照
我阅读了一些有解决方法的博客。我也试过了,但没有成功。
以下是解决方法的代码:
import {Injectable} from 'angular2/core';
import {BrowserXhr } from 'angular2/http';
@Injectable()
export class CORSBrowserXHr extends BrowserXhr {
build(): any {
let xhr = super.build();
xhr.withCredentials = true;
return <any>(xhr);
}
}
在bootstrap中我添加以下内容:
/// <reference path="../typings/browser.d.ts" />
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from "./app.component";
import {ROUTER_PROVIDERS} from "angular2/router";
import {APP_BASE_HREF} from 'angular2/router';
import {provide} from 'angular2/core';
import {LocationStrategy, HashLocationStrategy} from 'angular2/router';
import {HTTP_PROVIDERS} from "angular2/http";
import {BrowserXhr} from 'angular2/http';
import {CORSBrowserXHr} from "./CORSBrowserXHr.services";
bootstrap(AppComponent, [ROUTER_PROVIDERS, HTTP_PROVIDERS, provide(BrowserXhr, {useClass:CORSBrowserXHr}),
provide(LocationStrategy, {useClass: HashLocationStrategy})]);
我理解angular2正处于测试阶段,但我相信到现在为止他们必须提出一个CORS支持解决方案。如果有人有任何想法请发表评论。
提前致谢!!
答案 0 :(得分:3)
事实上,CORS有两个主要案例:
简单请求。如果我们使用HTTP方法GET
,HEAD
和POST
,我们就是这种情况。对于POST
方法,仅支持具有以下值的内容类型:text/plain
,application/x-www-form-urlencoded
,multipart/form-data
。即使您遇到这种情况,并且使用自定义标题(您在请求中由自己定义的标题),也会属于预检请求。
预检请求。如果您不是简单请求,则会执行第一个请求(使用HTTP方法OPTIONS
)来检查在跨域请求的上下文中可以执行的操作。
在您的情况下,您处于第二种情况(预检请求),因为您使用自定义标头(由您自己定义),Authorization
。
但相应的OPTIONS请求未在其响应中定义Access-Control-Allow-Origin
标头。这将允许浏览器确定您是否(例如localhost:3000)能够执行目标请求。
实际上,这不是Angular2应用程序中的问题,而是您尝试访问的服务器应用程序中的问题。后者应返回适当的CORS标头,如Access-Control-Allow-Origin
标头。否则您的浏览器将阻止请求...
这些文章可能会让您感兴趣:
答案 1 :(得分:1)
class MyBaseRequestOptions extends BaseRequestOptions {
headers: Headers = new Headers({
'X-Requested-With': 'XMLHttpRequest'
});
withCredentials: boolean = true;
}
bootstrap( AppComponent, [ provide(RequestOptions, {useClass: MyBaseRequestOptions}) ] );