请求的资源上没有“Access-Control-Allow-Origin”标头+响应具有HTTP状态代码401

时间:2017-05-15 22:38:55

标签: angular cors preflight

  

XMLHttpRequest无法加载http://192.168.1.253:8080/ ...不   请求中存在“Access-Control-Allow-Origin”标头   资源。因此不允许来源“http://localhost:4200”   访问。响应的HTTP状态代码为401。

非常常见的错误,许多可能的解决方案都没有奏效。我理解(我认为)CORS应该如何工作,我没有看到我的HTTP标头有什么问题,但它仍然无法正常工作

来自Chrome:

Request URL:http://192.168.1.253:8080/...
Request Method:OPTIONS
Status Code:200 OK
Remote Address:192.168.1.253:8080
Referrer Policy:no-referrer-when-downgrade
Response Headers
Access-Control-Allow-Headers:x-requested-with,accept,content-
type,authorization
Access-Control-Allow-Methods:POST, GET, PUT, PATCH, OPTIONS, DELETE
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3600
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Connection:keep-alive
Content-Length:0
Date:Mon, 15 May 2017 21:50:55 GMT
Expires:0
Pragma:no-cache
Server:...
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization,content-type
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:192.168.1.253:8080
Origin:http://localhost:4200
Pragma:no-cache
Referer:http://localhost:4200/...
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 
(KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36

我的理解是OPTIONS响应需要设置Access-Control-Allow-Origin标头并允许方法类型和标头值,它会这样做

下面相关的角度。我已经在标题中对各种不同的东西进行了相当多的不同组合,但没有任何作用

private getObject<T>(path: string): Promise<T> {
    return this.http.get(SERVER_URL + path, this.authenticationToken())
        .toPromise()
        .then(response => response.json() as T)
        .catch(this.handleError);
}

private authenticationToken() : RequestOptions {
    let login = JSON.parse(sessionStorage.getItem('currentLogin'));
    if (login && login.authenticationToken) {
        let headers = new Headers({ 
            'Authorization': 'Basic ' + login.authenticationToken,
            'Content-type': 'application/json', 
          });
        return new RequestOptions({ headers: headers });
    }
}

我感觉我错过了一些明显的东西,但它让我疯狂,任何帮助都表示赞赏。请注意,这适用于预先存在的Ember应用程序,因此我认为它不是服务器

2 个答案:

答案 0 :(得分:11)

  

响应的HTTP状态代码为401。

401表示身份验证错误。问题中的错误消息不是来自预检OPTIONS请求的响应。它似乎是针对您尝试发送的实际GET请求。

因此,基于该错误消息,最可能的情况是浏览器的预检OPTIONS请求成功,但由于身份验证失败,您的GET请求未成功。

因此服务器返回401响应/错误页面。许多/大多数Web服务器未配置为发送错误响应/页面的Access-Control-Allow-Origin响应标头。这也是你收到关于该标题丢失的消息的唯一原因。

但错误响应的缺少标头不是问题的原因;相反,401是。

所以看起来你可能想知道是什么导致服务器发送401响应 - 为什么你的身份验证失败了。如果您修复了这个问题,您似乎可能会收到服务器的响应,其中包含Access-Control-Allow-Origin响应标头符合预期。

答案 1 :(得分:9)

这是我们使用Angular和Ionic时发现的典型错误,问题出现是因为当您在应用的浏览器中加载的应用加载来自本地的来源的所有内容时地址http://localhost:4200,然后当您要将任何AJAX请求发送到 localhost:4200 以外的其他主机时,请求从与来源不同的任何点发出,则需要< strong> CORS (跨域资源共享)预检请求,以查看它是否可以访问资源。

解决方案是使用代理到后端,通过这种方式,您可以高举某些网址并将其发送到后端服务器。实施很简单:

1.-在项目的根文件夹中创建文件proxy.conf.js

2.-在您的proxy.conf.js文件中配置您的代理,假设您的新主机位于http://localhost:3000

&#13;
&#13;
const PROXY_CONFIG = [
    {
        context: [
            "/my",
            "/many",
            "/endpoints",
            "/i",
            "/need",
            "/to",
            "/proxy"
        ],
        target: "http://localhost:3000",
        secure: false
    }
]

module.exports = PROXY_CONFIG;
&#13;
&#13;
&#13;

3.-修改您的package.json文件,插入此"start": "ng serve --proxy-config proxy.conf.js",

4.-在您的服务中,将请求的路径从此http://localhost:3000/endpoints/any/path/that/you/use更改为此../endpoints/any/path/that/you/use(假设另一个主机位于localhost:3000且上下文为{{1} }})。

5.-从根文件夹开始运行angular:/endpoints;这将使用代理参数执行 npm start

如果您需要更多相关信息,请查看Proxy to backend Angular Cli documentation