Angular CORS 请求被阻止

Abr*_*ain 16 cors express angular

我正在尝试将我的 Angular 应用程序与 express 上的简单 REST 服务器连接起来。服务器只发送json数据响应请求。为了增加CORS支持,我使用了corsnpm 中的模块。在 Angular 应用程序上,我添加了HttpHeaders以下问题的说明:Angular CORS request blocks

这是我在 express 中设置 cors 选项的代码:`

// async CORS setup delegation
function corsOptsDelegator(req, cb) {
    let opts = {},
        origin = req.header('Origin');
    if(imports.allowedOrigins.indexOf(origin) === 1) opts.origin = true;
    else opts.origin = false;
    opts.optionsSuccessStatus = 200;
    opts.methods = ['POST', 'GET']; // allowed methods
    opts.credentials = true; // for passing/setting cookie 
    opts.allowedHeaders = ['Content-Type', 'Accept', 'Access-Control-Allow-Origin']; // restrict headers 
    opts.exposedHeaders = ['Accept', 'Content-Type']; // for exposing custom headers to clients; use for hash
    cb(null, opts);
}
`
Run Code Online (Sandbox Code Playgroud)

这是我将它添加到全局get处理程序的方式:

`
app.get('/', cors(corsOptsDelegator), (res, req, nxt) => {
    // only for adding cors on all requests
    nxt();
});
`
Run Code Online (Sandbox Code Playgroud)

以下是我设置 Angular 服务的方法:

`

export class ContentGetterService {

  private root: string;
  private corsHeaders: HttpHeaders;
  //private contents: string;

  constructor(private http: HttpClient) {
    this.root = 'http://localhost:8888';
    this.corsHeaders = new HttpHeaders({
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Access-Control-Allow-Origin': 'http://localhost:4200'
    });
    //this.contents = '';
   }

  getContent(subs: Array<string>): Observable<IContent> {
    return (() => {
      return this.http.get<IContent>( (() => {
        let r = this.root;
        subs.forEach((s, i, a) => {
          if(i === a.length-1) {
            r += s;
          }
          else {
            if(s !== '/') {
              r += s;
            }
          }
        });
        return r;
      })(), {
        headers: this.corsHeaders
      });

    })();
  }
  }
Run Code Online (Sandbox Code Playgroud)

浏览器警告: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8888/. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

谢谢。

The*_*eal 12

如果您使用的是 angular-cli,则可以使用代理:

proxy.conf.json

{
  "/api": {
    "target": "http://localhost:8888",
    "secure": false
  }
}
Run Code Online (Sandbox Code Playgroud)

将所有带有/api前缀的请求重定向到 localhost:8888 没有任何 cors 问题。

官方文档:https : //angular.io/guide/build#proxying-to-a-backend-server

  • 即使我像上面提到的那样使用代理,我仍然遇到这个问题。 (7认同)
  • 这是一个可行的解决方案,但是我坚持使用 cors。感谢您的努力。 (2认同)
  • 请注意,这仅适用于开发环境,不适用于生产环境 (2认同)

Abr*_*ain 6

首先,客户端的问题是由于 Firefox 选择处理飞行前 CORS 的行为。不是使用GET方法,而是使用方法OPTIONS。从我的代码中可以明显看出,我没有任何处理程序来处理OPTIONS. 经过一番谷歌搜索,我在 github 上发现了这篇文章:Express CORS 中间件。使用它并对我的客户端请求标头进行以下修改,我能够正确启动并运行它。这是代码:

CORS 中间件:

function myCors(req, res, nxt) {
    res.header('Access-Control-Allow-Origin', 'http://localhost:4200');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Origin, Content-Type, Accept, Accept-Language, Origin, User-Agent');
    if(req.method === 'OPTIONS') {
        res.sendStatus(204);
    }
    else {
        nxt();
    }
}`
Run Code Online (Sandbox Code Playgroud)

将其挂载到应用程序实例: app.use(myCors);

在 Angular 客户端服务上:

this.corsHeaders = new HttpHeaders({
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Access-Control-Allow-Origin': 'http://localhost:8888/'
});
// ... adding it to the request
getContent(subs: Array<string>): Observable<IContent> {
return (() => {
  return this.http.get<IContent>( (() => {
    let r = this.root;
    subs.forEach((s, i, a) => {
      if(i === a.length-1) {
        r += s;
      }
      else {
        if(s !== '/') {
          r += s;
        }
      }
    });
    return r;
  })(), {
    headers: this.corsHeaders
  });

})();
}
Run Code Online (Sandbox Code Playgroud)

感谢大家的时间和努力。

  • 使用“Access-Control-Allow-Origin”作为请求标头是否不正确?我认为标头应该只在服务器响应中使用。我认为您可以完全删除请求标头代码,只要服务器返回正确的标头,它就应该仍然可以正常工作。 (2认同)