2 个端口上的节点 rest api 和 angularJS 应用程序的 CORS 问题

Posted

技术标签:

【中文标题】2 个端口上的节点 rest api 和 angularJS 应用程序的 CORS 问题【英文标题】:CORS issue with node rest api and angularJS app on 2 ports 【发布时间】:2015-05-11 07:08:40 【问题描述】:

我的 angularJS 应用程序(在 localhost:9000 上)试图捕获我的节点服务器(在 localhost:9001 上)遇到了经典的 CORS 问题

这里是我的 api (app.js) 代码:

var cors = require('cors');
app.use(cors());
app.options('*', cors());

app.all('/*', function(req, res, next) 
    // CORS headers
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header('Access-Control-Allow-Methods',    'GET,PUT,POST,DELETE,OPTIONS');
    res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
    if (req.method == 'OPTIONS') 
        res.status(200);
        res.write("Allow: GET,PUT,POST,DELETE,OPTIONS");
        res.end();
     else 
        next();
    
);

如您所见,我尝试了这些解决方案都是徒劳的:

CORS in Node.js and AngularJS

Cors issue when rest api application server(express) and Angulars js application running on different port

这是 webapp 中的简单 $http 调用:

var req = 
    method: 'GET',
        url: 'localhost:9001/memories'
    ;
    $http(req).
        success(function(data, status, headers, config) 
            // this callback will be called asynchronously
            // when the response is available
            reutrnStatus.success = true;
            reutrnStatus.msg = status;
            memories = data;
        ).
        error(function(data, status, headers, config) 
            // called asynchronously if an error occurs
            // or server returns response with an error status.
            reutrnStatus.success = false;
            reutrnStatus.msg = status;
        );

我也在 webapp 中尝试了一些解决方案(在 app.js 中):

// Enable AngularJS to send its requests with the appropriate CORS headers
// globally for the whole app:
.config(['$httpProvider', function ($httpProvider) 
    $httpProvider.defaults.useXDomain = true;
    /**
     * Just setting useXDomain to true is not enough. AJAX request are also
     * send with the X-Requested-With header, which indicate them as being
     * AJAX. Removing the header is necessary, so the server is not
     * rejecting the incoming request.
     **/
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
]);

但我快要放弃了,因为它仍然无法正常工作......这给了我同样的错误:

XMLHttpRequest cannot load localhost:9001/memories. Cross origin
requests are only supported for protocol schemes: http, data, chrome, 
chrome-extension, https, chrome-extension-resource.

为了完全清楚,我遵循了其余 api 的教程:

https://blog.jixee.me/how-to-write-an-api-in-one-week-part-2/

【问题讨论】:

当您的服务器应该在 localhost:9000 上运行时,为什么 localhost:9001 出现错误(正如您在问题中所述)。你确定调用应该是 localhost:9000,这是你的服务器端 API? 你说得对,它是我在 9000 上的应用程序,其余的 api 在 9001 上;) 您确定您是通过 localhost 而不是file://protocol 访问您的角度应用程序吗?看起来正在进行 ajax 调用的页面不在http:// 或任何给定协议上。 【参考方案1】:

您正在向未知协议发出请求。

Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.

你需要改变这个:

method: 'GET',
    url: 'localhost:9001/memories'
;

...到这个:

method: 'GET',
    url: 'http://localhost:9001/memories'
;

或者,您可以将其设置为 //localhost:9001/memories,如果您同时通过 httphttps 提供资源,浏览器将使用当前协议。

虽然不相关,但您的回调在变量名中有拼写错误。

【讨论】:

以上是关于2 个端口上的节点 rest api 和 angularJS 应用程序的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot REST API 不支持的媒体类型

无状态 REST 服务器上的 Google API 回调

连接到节点 REST api 的应用程序被客户防火墙阻止

如何在 Nginx 中为 Janus REST api 和 socket api 设置反向代理?

Kubernetes服务组件

API设计与开发实践第2篇 Restful API 设计最佳实践的四个重要改进