3

我正在开发使用托管在同一台机器上的两台服务器的应用程序,一个是 apache,它将作为基本主机来提供 php 页面,另一端 nodejs 用于通信 rest api,整个应用程序建立在骨干/木偶/requirejs/引导程序。

说到这一点,我的正常页面是从 apache 服务器加载的,例如,

http://192.168.20.62/project/design.php

我已经像这样配置了我的模型,

define(['backbone'],function(Backbone){
'use strict';

return Backbone.Model.extend({
    url:"http://192.168.20.62:9847/page",
    defaults: {
        ...
    }
});

});

当我尝试保存模型时,我遇到了 ajax 跨域调用问题,并且我的保存通信出现错误,以下是节点/快递服务器,

var express = require('/root/node_modules/express');


var app = express();

app.configure(function () {
    app.use(express.json());
    app.use(express.urlencoded());
    app.use(function (req, res, next) {
        res.setHeader('Access-Control-Allow-Origin', 'http://192.168.20.62:9847');
        res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
        res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
        res.setHeader('Access-Control-Allow-Credentials', true);
        next();
    });

})

app.post('/page', function(request, response){

    console.log(request.body);
    response.send(request.body);

});

app.listen(9847);

如您所见,我已经在服务器代码中编写了一些补丁,但仍然相同,我还在两者的根级别添加了 .htaccess

http://192.168.20.62 

http://192.168.20.62:9847 

使用以下代码,

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

但是无论如何事情都没有帮助,如果我通过禁用网络安全来运行 chrome,那么事情就会正常工作。

chrome.exe --disable-web-security

各位大神能帮我解一下这个谜题吗,先谢谢了。

以下是来自 chrome javascript 控制台的错误消息

OPTIONS http://192.168.20.62:9847/page Origin http://192.168.20.62 is not allowed by Access-Control-Allow-Origin. jquery-2.0.3.min.js:6

XMLHttpRequest cannot load http://192.168.20.62:9847/page. Origin http://192.168.20.62 is not allowed by Access-Control-Allow-Origin. 
4

2 回答 2

2

糟糕,我发现了问题,我为白名单设置了错误的 url。

res.setHeader('Access-Control-Allow-Origin', 'http://192.168.20.62');

我必须将生成跨域的源 URL 列入白名单,这是使事情运行所需的唯一更改。

这也对浏览器版本有影响,当我发布这个问题时,我正在检查 Firefox 版本 24.0.*,当我升级 25.0 时,它出人意料地停止产生跨域错误。但是 Chrome 仍然会给出自然的跨域错误,当我仔细阅读 chrome 的错误消息时,我才知道我已将错误的 url 列入白名单。

XMLHttpRequest cannot load http://192.168.20.62:9847/page. The 'Access-Control-Allow-Origin' whitelists only 'http://192.168.20.62:9847'. Origin 'http://192.168.20.62' is not in the list, and is therefore not allowed access.

于 2013-12-02T05:20:08.040 回答
1

如果您不必处理 WebSockets,那么通过mod_proxy将 Node.js 放在 Apache 后面:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so

# disable use as forward proxy
ProxyRequests Off
# don't handle Via: headers - we don't care about them
ProxyVia Off
# no need to transport host name - not doing virtual hosting
ProxyPreserveHost Off

ProxyPass         /page/   http://192.168.20.62:9847/page/
ProxyPassReverse  /page/   http://192.168.20.62:9847/page/

# If you get HTTP status code 502 (Bad Gateway), maybe this could help
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1

在您的网页中,您可以使用与 Apache 相同的端口访问您的 API,并且跨域/同源策略没有任何问题。

您现在只需分离您的 URI,例如 /page/ 仅存在于 node.js 应用程序中。

如果您仅通过 node.js 提供 REST(无 HTML/CSS/图像),则使用JSONP将是另一种选择。这是一个很好的简短描述如何在 Express 中处理 JSONP

于 2013-11-13T09:09:04.310 回答