【问题标题】:Angular2-Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resourceAngular2-对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头
【发布时间】:2016-12-24 10:33:27
【问题描述】:

我在 Angular 2 中调用 http 帖子。这在 post man 中运行良好,但是当我在 Angular 2 中实现此 API 调用时,我得到 No 'Access-Control-Allow' 错误。这是我的代码

getInspections(): Observable<IInspection[]> {
        if (!this.inspections) {
            let body =JSON.stringify({"Statuses":["Submitted", "Opened"]});
            let headers = new Headers({ 'Content-Type': 'application/json' });

            headers.append('Access-Control-Allow-Origin','*');
            let options = new RequestOptions({ headers: headers });

            return this.http.post(this._baseUrl + '/api/Inspect/ListI',body,options)
                .map((res: Response) => {
                    this.inspections = res.json();
                    return this.inspections;
                })
                .catch(this.handleError);
        }
        else {
            //return cached data
            return this.createObservable(this.inspections);
        }
    }

或者我可以这样做吗?只需传递标题而不是选项

getInspections(): Observable<IInspection[]> {
        if (!this.inspections) {
            let body =JSON.stringify({"Statuses":["Submitted", "Opened"]});
            let headers = new Headers({ 'Content-Type': 'application/json' });

            //headers.append('Access-Control-Allow-Origin','*');
          //  let options = new RequestOptions({ headers:headers });

            return this.http.post(this._baseUrl + '/api/Inspect/ListI',body,headers)
                .map((res: Response) => {
                    this.inspections = res.json();
                    return this.inspections;
                })
                .catch(this.handleError);
        }
        else {
            //return cached data
            return this.createObservable(this.inspections);
        }
    }

【问题讨论】:

  • 您可以直接传递标头(我猜它需要是像 {headers} 这样的对象(虽然不确定)但这与您的 CORS 错误完全无关。

标签: rest angular cors angular2-http


【解决方案1】:

CORS 标头,如

headers.append('Access-Control-Allow-Origin','*');

需要由服务器提供。将它们添加到客户端是没有意义的。

【讨论】:

  • 我使用的是第 3 方 api,所以如何在此处添加标题
  • 这可能意味着所有者不希望xou以这种方式使用API​​。您可以通过您控制的服务器中继请求来解决问题。 CORS 我们仅与从浏览器发出的请求相关,而不是从服务器发出的请求。
【解决方案2】:

当使用非标准标头(json 显然被认为是非标准的)时,会执行飞行前检查以询问是否可以执行请求的操作(在本例中为“post”)。只有服务器可以使用许可标头进行响应。您的响应方式取决于您的服务器语言。在我的 webapi2 中,我在 WebAppConfig 中实现了 cors

 var cors = new EnableCorsAttribute("http://localhost:3000", "*", "GET, HEAD, OPTIONS, POST, PUT");
        cors.SupportsCredentials = true;
        config.EnableCors(cors);

请注意,对于实时服务器,您可以将 localhost 引用替换为 Web 配置列表(或调用者所在的特定位置)。只有在使用身份验证时才需要 SupportsCredentials。

为了处理飞行前,我在 Globals.asax 中添加了一个方法,它只是截取飞行前消息并返回足够的数据以使帖子继续前进。

protected void Application_BeginRequest()
    {
        if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
        {
            var origin = HttpContext.Current.Request.Headers["Origin"];

            Response.Headers.Add("Access-Control-Allow-Origin", origin);
            Response.Headers.Add("Access-Control-Allow-Headers", "content-type, withcredentials, Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            Response.Headers.Add("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS, POST, PUT");

            Response.Flush();
        }
    }

请注意,我通过将来源反射回来有点作弊 - 这在生产环境中是不安全的,应该列出特定的服务器,否则您的安全性太松散了。

请注意,有些开发者作弊。 - 如果您在本地主机上的 Internet Explorer 上运行(出于开发目的),那么 ie 会忽略大多数其他浏览器不这样做的端口,从而使事情变得更容易。 Chrome 还有一个 CORS 增强功能,可以为您添加标题。最后你会看到很多使用'*'返回的代码(允许所有) - 无论如何都要使用它们来让代码工作,但在发布之前更积极地锁定它们。

【讨论】:

  • 当你说Only the server can respond with the permissive headers. 和后来There is also a CORS enhancement for Chrome which adds the headers for you. Chrome 在客户端不是吗?
  • 建议您调查 Chrome CORS 增强功能的作用,这应该可以消除您的困惑。这种增强可以解决 DEV 环境中的有限问题。生产需要完整的答案。
猜你喜欢
  • 2017-09-08
  • 2016-02-23
  • 2018-05-06
  • 1970-01-01
  • 2017-11-11
  • 2017-04-09
  • 2017-10-10
  • 2020-12-07
相关资源
最近更新 更多