首页 > 解决方案 > Angular 8 Express Post 引发 COR 错误

问题描述

是的,我知道您通常可以通过将源通配符设置为“*”来解决这些问题,但我使用的是“凭据:true”,所以这将我的正常解决方案抛到了窗外。

我遇到的问题是,当我尝试向 Express 执行发布请求时,它似乎首先作为 OPTIONS 提交,然后被重定向为 GET,然后再次重定向为 POST。

我所有的“Access-Control-Allow-XXXX”标头都出现在原始选项中,但随后在重定向中丢失。

从浏览器显示的错误是;

从源“null”访问“ http://localhost:4200/ ”处的 XMLHttpRequest(从“ http://localhost:3000/api/save ”重定向)已被 CORS 策略阻止:请求标头字段访问控制- Access-Control-Allow-Headers 在预检响应中不允许使用 allow-origin。

这是我的 express cors 设置,设置了动态原点,因为我认为直接可能一直在寻找 API 地址作为可能的原点,然后 undefined 和 null 因为我对它感到恼火;

var app = express();
var port = process.env.PORT || 3000;

whitelist = [UI_BASE_URL, API_BASE_URL, undefined, null];

app.use(
  cors({
    allowedHeaders: [
      'Origin',
      'X-Requested-With',
      'Content-Type',
      'Accept',
      'X-Access-Token',
      'Access-Control-Allow-Origin',
      'Access-Control-Allow-Headers',
      'Access-Control-Allow-Methods'
    ],
    preflightContinue: false,
    credentials: true,
    origin: function(origin, callback) {
      if (whitelist.indexOf(origin) !== -1) {
        callback(null, true);
      } else {
        callback(new Error('Not allowed by CORS'));
      }
    },
    methods: 'GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE',
  })
);

这是来自 Angular 的服务调用

const httpOptions = {
  headers: new HttpHeaders({
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT',
    'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
  }),
};

save(myData): Observable<any> {
    return this.http.post(
      this.workSpaceReportURL + 'save',
      {
        data: myData,
        withCredentials: true,
      },
      httpOptions
    );
  }

并且因为它们可能有用,来自 POST 的请求和响应标头。

回复

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:4200
Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate
Connection: keep-alive
Content-Length: 43
Content-Type: text/plain; charset=utf-8
Date: Mon, 11 Nov 2019 14:50:31 GMT
Expires: 0
Location: http://localhost:4200
Pragma: no-cache
Set-Cookie: connect.sid=s%3Aj3wYyE_I14o6b_C-L6EDnOxesW0CBVks.WEwBNiQegZ1ufG2d40%2BF4BGfbCWPbOz9FS4Kj%2BC14Pc; Path=/; Expires=Mon, 18 Nov 2019 13:30:31 GMT; HttpOnly
Strict-Transport-Security: max-age=15552000; includeSubDomains
Surrogate-Control: no-store
Vary: Origin, Accept
X-Content-Type-Options: nosniff
X-DNS-Prefetch-Control: off
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 184
Content-Type: application/json
Host: localhost:3000
Origin: http://localhost:4200
Referer: http://localhost:4200/data-controller
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36

我已经尝试了许多在 SO 上遇到的不同解决方案,但它们通常最终会被通常的通配符来源修复。

感谢您提出的任何建议。

标签: node.jsangularcors

解决方案


好的,我想我意识到解决方案是什么。我只是花了很长时间才意识到。

我设法在没有注意到的情况下删除了 Content-Type,并将 withCredentials 作为正文的一部分传递,而不是 httpOptions (我认为这是我最初的问题)。

如果它在几年后帮助其他人,httpOptions 和 post 应该如下所示。

我现在要羞愧地站在服务器机房里。

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json'
  }),
  withCredentials: true,
};

save(myData): Observable<any> {
    return this.http.post(
      this.workSpaceReportURL + 'save',
      {
        myData,
      },
      httpOptions
    );
  }

推荐阅读