【问题标题】:Angular 8 Express Post Throws a CORs ErrorAngular 8 Express Post 引发 COR 错误
【发布时间】:2020-03-07 07:01:21
【问题描述】:

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

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

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

浏览器显示的错误是;

CORS 策略已阻止从源“null”访问“http://localhost:4200/”处的 XMLHttpRequest(从“http://localhost:3000/api/save”重定向):Access-Control 不允许请求标头字段 access-control-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.js angular cors


    【解决方案1】:

    您似乎使用了一种旧方法来添加线头。你试过这样做吗?

    var cors = require('cors')
    
    app.use(cors())
    

    确保在运行其他应用程序之前运行最后一个。使用

    【讨论】:

    • 您好 TK,感谢您的回复。如果我将其剥离回 app.use(cors()) 我得到“当请求的凭据模式为“包含”时,响应中的“Access-Control-Allow-Origin”标头的值不能是通配符“*” '”。由于凭据,我至少需要来源。
    • 我相信这意味着你不能因为安全问题。请尝试使用您使用的协议+域+端口,它看起来像localhost:4200。这应该有效。 app.use(cors({ origin: 'http://localhost:4200' }));
    • 谢谢,我刚刚试了一下(这也意味着在我的服务调用中使用“withCredentials: true”,但不幸的是它完全破坏了身份验证。
    【解决方案2】:

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

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

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

    我现在要去耻辱的服务器机房。

    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json'
      }),
      withCredentials: true,
    };
    
    save(myData): Observable<any> {
        return this.http.post(
          this.workSpaceReportURL + 'save',
          {
            myData,
          },
          httpOptions
        );
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      • 2019-10-18
      • 2020-05-22
      • 1970-01-01
      • 2016-02-25
      • 1970-01-01
      相关资源
      最近更新 更多