Angular 2 : Support for withCredentials and useXDomain

标签 angular cross-domain angular2-services django-cors-headers

我是 angular2 的新手。我正在尝试登录到我的 Django 服务器,它是来自本地主机的生产服务器,我目前正在其中编写前端代码。另外,我将端口转发到我的生产服务器。 我不断收到 CORS 问题。 这是我在控制台中收到的错误:

XMLHttpRequest cannot load https://www.smartkart.ca/api/user/login/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.

我已经编写了我的 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': '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2d464c5f4c436d5e404c5f59464c5f59034e4c" rel="noreferrer noopener nofollow">[email protected]</a>', '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': '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="166273656256657b7764627d776462387577" rel="noreferrer noopener nofollow">[email protected]</a>', 'password': 'blahblah'});     
    var params = data;  
    var headers = new Headers ();
    headers.append('Accept', 'application/json');
    headers.append('Authorization', 'Basic ' + btoa('<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="345f5546555a7447595546405f5546401a5755" rel="noreferrer noopener nofollow">[email protected]</a>: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())

};

}

这是我在浏览器的网络选项卡中看到的内容

enter image description here

现在,如果我拿走授权 header ,我会登录并取回 csrf token ,但由于 CORS 问题,我永远无法从服务器获得任何响应。这是一个快照

enter image description here

我读了一些博客,其中有解决方法。我也尝试过,但没有成功。

这是我的解决方法代码:

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 支持的解决方案。如果有人有任何想法请评论。

提前致谢!!

最佳答案

其实CORS主要有两种情况:

  • 简单请求。如果我们使用 HTTP 方法,就会出现这种情况 GET , HEADPOST 。以POST为例方法,仅支持具有以下值的内容类型: text/plain , application/x-www-form-urlencoded , multipart/form-data 。即使您处于这种情况,并且如果您使用自定义 header (您在请求中自己定义的 header ),您也会陷入预检请求中。

  • 预检请求。当您处理的不是简单请求时,会执行第一个请求(使用 HTTP 方法 OPTIONS )来检查在跨域请求的上下文中可以执行哪些操作。

就您而言,您处于第二种情况(预检请求),因为您使用自定义 header (由您自己定义),即 Authorization一个。

但是相应的 OPTIONS 请求没有定义Access-Control-Allow-Origin其响应中的 header 。这将允许浏览器确定您(例如 localhost:3000)是否能够执行目标请求。

事实上,这不是您的 Angular2 应用程序中的问题,而是您尝试访问的服务器应用程序中的问题。后者应该返回适​​当的 CORS header ,例如 Access-Control-Allow-Origin一。否则您的浏览器将阻止该请求...

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

关于 Angular 2 : Support for withCredentials and useXDomain,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36527149/

相关文章:

.net - 如何通过IIS中的代理来防止跨域问题?

css - Font-awesome 无法在 Firefox 上正确显示/如何通过 CDN 出售?

angular2 fullcalendar 不工作

angular - 如何在 Angular 2 中获取表单数据

Angular 4 找不到名称(泛型)

c# - Asp.net core 2.0 Angular 模板 : add identity and authentication

google-chrome-extension - XMLHttpRequest 在没有明显权限的情况下成功?也许是 CORS?

angular - 测试 - 无法解析 (ClassName) 的所有参数

angular - 如何从 Angular 导入中删除 .js 后缀

javascript - 转换 RxJS Observable