CORS - OPTIONS ... 404 (未找到)。

8

你好,我在处理CORS时遇到问题。

总体结构:

Angular 4将表单数据发送到我的API。当我发送有关联系表单的信息时,执行saveForm()函数。

app.component.ts

saveForm() {

    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    let requestOptions = new RequestOptions({ headers: headers });

    // Encode JSON as string to exchange data to web server.
    this.data = JSON.stringify(this.myContact);

    this.http.post('https://pablocordovaupdated.herokuapp.com/api', this.data, requestOptions).subscribe(res => {
            let result = res.json();
            if(result['result'] == 'success') {
                this.successMessage = true;
            }
        }
    );

}

问题的根源在于我使用POSTContent-Type->application/json来发送数据,而根据定义,这会导致CORS - preflighted request出现问题,这里更多的定义:有关预检请求的链接

这意味着在Angular 4将数据发送到服务器之前,它会向服务器询问是否支持使用动词OPTION接收我的数据,如果服务器的响应是良好的,那么Angular 4会将表单数据发送过去。

问题:

控制台总是会显示以下错误信息:

OPTIONS https://pablocordovaupdated.herokuapp.com/api 404 (未找到)

XMLHttpRequest无法加载https://pablocordovaupdated.herokuapp.com/api。预检请求的响应未通过访问控制检查:所请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许从原始站点'https://pablocordova.herokuapp.com'进行访问,响应的HTTP状态码为404。

XHR加载失败:POST"https://pablocordovaupdated.herokuapp.com/api"。

ERROR Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers…}

我尝试过的方法:

到目前为止,我了解到问题是由于https://pablocordovaupdated.herokuapp.com/api没有返回OPTIONS的答案所引起的

那么我尝试通过两种方式解决这个问题:

使用cors包 CORS package,我按照文档进行了配置。

var express = require('express');
var cors = require('cors');
...
var app = express();
...
app.options('/api', cors());
app.post('/api', cors(), function(req, res, next) {

    // Proccess to send this data via email
    // and also save in data base(only for learning)

});

但是我在控制台中收到了相同的错误。
手动配置标题,可以通过StackOverFlow讨论Github讨论进行操作。
该代码插入到每个需要编写标题的路由中,例如我的情况:
app.post('/api', function(req, res, next) {

    if (req.method === 'OPTIONS') {
          console.log('!OPTIONS');
          var headers = {};
          // IE8 does not allow domains to be specified, just the *
          // headers["Access-Control-Allow-Origin"] = req.headers.origin;
          headers["Access-Control-Allow-Origin"] = "*";
          headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
          headers["Access-Control-Allow-Credentials"] = false;
          headers["Access-Control-Max-Age"] = '86400'; // 24 hours
          headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
          res.writeHead(200, headers);
          res.end();
    } else {
        // Process to send this data via email
        // and also save in data base(only for learning)
    } 

});

问题在于从未执行console.log('!OPTIONS');

这里我尝试了简单的方法:

app.post('/api', function(req, res, next) {
    console.log('!I AM YOUR FATHER');
    ...
});

但是从未打印。

注意:我尝试使用heroku logs查看此消息,因为整个页面在Heroku中。

但是这样做我也收到了相同的错误。

更多信息:

当调用.../api时,我有以下头文件。

**GENERAL**:

Request URL:https://pablocordovaupdated.herokuapp.com/api
Request Method:OPTIONS
Status Code:404 Not Found
Remote Address:23.21.185.158:443
Referrer Policy:no-referrer-when-downgrade

**RESPONSE HEADERS**:

HTTP/1.1 404 Not Found
Connection: keep-alive
Server: Cowboy
Date: Wed, 10 May 2017 04:14:45 GMT
Content-Length: 494
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache, no-store

**REQUEST HEADERS**:

OPTIONS /api HTTP/1.1
Host: pablocordovaupdated.herokuapp.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: https://pablocordova.herokuapp.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Referer: https://pablocordova.herokuapp.com/
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: es-ES,es;q=0.8

问题:

这是我的真正问题,还是我理解有误?或者 我应该怎么做来解决这个问题?或者 有什么建议吗?

谢谢。


1
哇,你做了非常详细的研究。但是你错过了一个主要问题。响应状态码。它是404。请验证您的端点URL是否正确。! - Jeyenth
谢谢,我简直不敢相信我没意识到终端节点 URL 是错误的,谢谢! - Pablo Cesar Cordova Morales
大多数情况下,问题可能只是一个小错误,我们会考虑所有超级棒的场景。但这就是我们不断学习的方式。继续学习...赞扬... - Jeyenth
1个回答

5
问题似乎是:https://pablocordovaupdated.herokuapp.com/api始终返回404:
$ curl -i https://pablocordovaupdated.herokuapp.com/api
HTTP/1.1 404 Not Found

也就是说,服务器并没有对 OPTIONS 请求做任何特殊/不同的处理 - 所有请求都只是返回 404 错误。
app.post('/api', function(req, res, next) {
    console.log('!I AM YOUR FATHER');
    ...
});
我不是很清楚Express如何处理这种情况,但可能需要配置它以发送某种响应路由,而不仅仅是在服务器端上使用console.log。当我查看https://pablocordovaupdated.herokuapp.com/api的内容时,我只看到一个通用的Heroku 404页面,因此它并不是从您的应用程序提供的,而是由Heroku提供的。例如,该404页面的内容如下:
<iframe src="//www.herokucdn.com/error-pages/no-such-app.html"></iframe>

也就是说,似乎您的应用程序代码在任何情况下都没有按预期处理该URL的请求。因此,看起来这是您需要首先修复的问题。

谢谢!!! 我不知道为什么我没有意识到真正的终端点必须是: https://pablocordova.herokuapp.com/api,再次感谢,我一直在尝试解决这个问题将近2个小时。 - Pablo Cesar Cordova Morales

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接