【问题标题】:Apache and Nodejs cross domain ajax issueApache 和 Nodejs 跨域 ajax 问题
【发布时间】:2013-11-25 17:02:23
【问题描述】:

我正在开发一个应用程序,其中我使用了两台托管在同一台机器上的服务器,一个是 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 --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. 

【问题讨论】:

    标签: ajax node.js apache cross-domain marionette


    【解决方案1】:

    糟糕,我发现了问题,我为白名单设置了错误的 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.

    【讨论】:

      【解决方案2】:

      如果您不必处理 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 将是另一种选择。这是一个很好的+简短描述how to handle JSONP in Express

      【讨论】:

      • 谢谢哥们,JSONP 确实有效,一个快速的问题是现在在 express/node 中处理 JSOP 的最佳方法是什么,我的意思是现在如何解析 jsonp 对象?
      • 查看编辑。也许您应该考虑使用 mod_proxy 的解决方案。如果您有时想使用 HTTPS 为您的页面/应用程序提供服务,您只需要一个 IP 地址。如果您想对节点的请求进行负载平衡,您可以使用 Apache 模块来实现。而且你减少了开放端口的数量。
      • 嗯,听起来合乎逻辑,我一定会尝试的。再次感谢,非常感谢
      猜你喜欢
      • 2013-10-08
      • 2011-07-05
      • 1970-01-01
      • 2011-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-05
      相关资源
      最近更新 更多