Angular2:支持withCredentials和useXDomain

Angular2:支持withCredentials和useXDomain,angular,cross-domain,angular2-services,django-cors-headers,Angular,Cross Domain,Angular2 Services,Django Cors Headers,我是安格拉尔的新手。我正在尝试登录到Django服务器,这是一个来自localhost的生产服务器,我目前正在编写前端代码。此外,我正在将端口转发到我的生产服务器。 我一直在搞CORS问题。 以下是我在控制台中得到的错误: 无法加载XMLHttpRequest。对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“访问控制允许来源”标头。因此,不允许访问源“” 我写过我的HTTpService,读过几乎所有的博客,想找到一个解决方案,但运气不好。我相信我需要使用withCredentials

我是安格拉尔的新手。我正在尝试登录到Django服务器,这是一个来自localhost的生产服务器,我目前正在编写前端代码。此外,我正在将端口转发到我的生产服务器。 我一直在搞CORS问题。 以下是我在控制台中得到的错误:

无法加载XMLHttpRequest。对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“访问控制允许来源”标头。因此,不允许访问源“”

我写过我的HTTpService,读过几乎所有的博客,想找到一个解决方案,但运气不好。我相信我需要使用withCredentials:true属性。我读了一些博客,修改了我的代码以支持凭据,但运气不好

以下是我的代码片段:

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);
}
}
从'angular2/core'导入{Injectable};
从'angular2/http'导入{BrowserXhr};
@可注射()
导出类CORSBrowserXHr扩展了BrowserXhr{
build():任何{
设xhr=super.build();
xhr.withCredentials=true;
返回(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/platform/browser'导入{bootstrap};
从“/app.component”导入{AppComponent};
从“angular2/ROUTER”导入{ROUTER_PROVIDERS};
从“angular2/路由器”导入{APP_BASE_HREF};
从'angular2/core'导入{provide};
从“angular2/router”导入{LocationStrategy,HashLocationStrategy};
从“angular2/HTTP”导入{HTTP_PROVIDERS};
从'angular2/http'导入{BrowserXhr};
从“/CORSBrowserXHr.services”导入{CORSBrowserXHr}”;
bootstrap(AppComponent,[ROUTER_PROVIDERS,HTTP_PROVIDERS,provide(BrowserXhr,{useClass:CORSBrowserXHr}),
提供(LocationStrategy,{useClass:HashLocationStrategy}]);
我知道angular2正在测试阶段,但我相信现在他们一定已经找到了CORS支持的解决方案。如果有人有任何想法,请评论

提前谢谢

class MyBaseRequestOptions extends BaseRequestOptions {
  headers: Headers = new Headers({
    'X-Requested-With': 'XMLHttpRequest'
  });
  withCredentials: boolean = true;
}

bootstrap( AppComponent, [ provide(RequestOptions, {useClass: MyBaseRequestOptions}) ] );

你能试一下吗,从:

事实上,CORS有两种主要情况:

  • 简单请求。如果我们使用HTTP方法
    GET
    HEAD
    POST
    ,那么我们就是这样。对于
    POST
    方法,仅支持具有以下值的内容类型:
    text/plain
    application/x-www-form-urlencoded
    多部分/表单数据
    。即使在这种情况下,如果使用自定义头(在请求中由您自己定义的头),您也会陷入预引导请求

  • 预引导请求。如果不是简单请求,则会执行第一个请求(使用HTTP方法
    OPTIONS
    ),以检查在跨域请求的上下文中可以执行哪些操作

在您的情况下,您处于第二种情况(预飞行请求),因为您使用了一个自定义头(由您自己定义),即
授权

但是相应的选项请求没有在其响应中定义
访问控制允许来源
头。这将允许浏览器确定您(例如localhost:3000)是否能够执行目标请求

事实上,这在Angular2应用程序中不是问题,但在您尝试访问的服务器应用程序中却是问题。后者应返回相应的CORS头,如
Access Control Allow Origin
one。否则您的浏览器将阻止该请求

您可能会对这些文章感兴趣:


我需要在引导提供程序中注入它,还是可以直接在我的httpService构造函数中使用它?您可以在主构造函数中添加身份验证构造函数代码,在主构造函数中注入Http,这就足够了。是的,尝试了,没有起作用。我将它直接添加到我的httpservice构造中,您可以为您的问题创建一个Plunker,以便易于检查。?当然,可以这样做。一旦我完成了plunker,我会在这里发表评论