我正在开发我在同一台机器上使用两台服务器的应用程序,一个是 apache,它将作为提供 php 页面和其他侧 nodejs 的基本主机来通信 rest API,整个应用程序建立在主干/木偶/requirejs/bootstrap 上。
说到这里,我的正常页面是从 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 --禁用网络安全
你们能帮我解决这个难题吗,提前谢谢。
以下是来自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.
糟糕,我解决了问题,我为白名单设置了错误的网址。
res.setHeader('Access-Control-Allow-Origin', 'http://192.168.20.62');
我必须将生成跨域的源URL列入白名单,这是使事情运行的唯一更改。
这也会影响浏览器版本,当我发布此问题时,我正在使用 Firefox 版本 24.0.* 进行检查,当我升级 25.0 时,它已停止生成跨域错误。但是Chrome仍然给出了自然的跨域错误,当我仔细阅读chrome的错误消息时,我开始知道我已将错误的网址列入白名单。
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.
如果你不必处理 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/Images),使用JSONP将是另一种选择。这里有一个很好的+简短的描述,如何在Express中处理JSONP