如何正确配置一个反向代理与Apache,用于跨域AJAX



需要开发一个web应用程序,同时高度依赖于API,但同时不能驻留在与API本身相同的域中,这是相当棘手的绕过"同源策略"时,异步HTTP请求(AJAX)。有一次,有人建议我在我的计算机上安装WAMP(运行Windows 7),并使用Apache配置反向代理。在告诉我为IP 127.0.0.1创建一个名为dev的别名(我在c:windowssystem32driversetchosts的文件中这样做了)之后,同一个人给了我下面添加到httpd.conf文件中的Apache指令:

LoadModule headers_module modules/mod_headers.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so
Listen 127.0.0.1:8080
ProxyRequests off
<Proxy *>
                Order deny,allow
                Deny from all
                Allow from 127.0.0.1
</Proxy>
<VirtualHost dev:8080>
                ProxyPass / https://app.somesite.com:5002/
                ProxyPassReverse / https://app.somesitecom:5002/
                ProxyPassReverseCookieDomain app.somesite.com dev
                Header edit Location ^https://dev(:8080)?(.+)$ http://dev$1$2
                Header edit Set-Cookie "(^.+); secure; HttpOnly$" "$1; HttpOnly"
                SSLProxyEngine on
    SSLProxyVerify none
</VirtualHost>

由于在配置服务器方面我是一个完全的新手,所以我只是简单地粘贴了指令,幸运的是,代理工作了。当我使用浏览器的地址栏访问时,它会从API返回正确的响应,例如http://dev:8080/a/w/currencies

不幸的是,一个AJAX请求相同的URL(下面的代码)使Chrome给我XMLHttpRequest cannot load http://dev:8080/a/w/currencies. Origin http://dev is not allowed by Access-Control-Allow-Origin.错误。

$.ajax({
    url: "http://dev:8080/a/w/currencies",
    type: "GET",
    dataType: "json",
    data: {
    },
    success: function(data){
        console.log(data);
    }
}); 

那么,为了让这个代理与AJAX一起工作,还必须做些什么呢?有人告诉过我一些关于alias指令的事情,但不够具体和清楚,所以对我没有经验的大脑来说,它没有多大意义。

PS:另外,我被告知"问题是你从dev:80获取文件并ajax到dev:8080"。鉴于我缺乏经验,这两件事都说不通。

您有一个具有公共IP的服务器,并且apache正在其上运行。现在你想在局域网上托管你的应用程序,也希望它们可以在互联网上访问,重要的是这些应用程序仍然在局域网上的机器上运行。

                           |--------------192.168.1.3
                           |            (internal3.example.com)
                           |
                           |--------------192.168.1.4
                           |            (internal4.example.com)
  (Public IP )             |
            A--------------|
(reverse proxy server)     |
  (192.168.1.25)           |
example.com                |
                           |--------------192.168.1.1
                           |            (internal1.example.com)
                           |
                           |--------------192.168.1.2
                           |            (internal2.example.com)

我使用Ubuntu来托管Apache,在基于Debian系统的情况下,vhost定义网站的定义是在

/etc/输入/sites-enabled/* . conf

其中*conf对应

internal1.conf internal2.conf internal3.conf internal4.conf

这些站点的vhost定义如下

/etc/输入/sites-enabled/internal1.example.conf

<virtualhost *:80>
    ServerAdmin webmaster@localhost
    ServerName internal1.example.com
    ProxyRequests off
    <proxy *>
        Order deny,allow
        Allow from all
    </proxy >
    ProxyPass / http://192.168.1.1/
    ProxyPassReverse / http://192.168.1.1/ 
</VirtualHost>

/etc/输入/sites-enabled/internal2.example.conf

<virtualhost *:80>
      ServerAdmin webmaster@localhost
      ServerName internal2.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.2/
      ProxyPassReverse / http://192.168.1.2/
</VirtualHost >

/etc/输入/sites-enabled/internal3.example.conf

<virtualhost *:80>
      ServerAdmin webmaster@localhost
      ServerName internal3.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.3/
      ProxyPassReverse / http://192.168.1.3/
</VirtualHost >

/etc/输入/sites-enabled/internal4.example.conf

<virtualhost *:80>
    ServerAdmin webmaster@localhost
    ServerName internal4.example.com
    ProxyRequests off
    <proxy *>
        Order deny,allow
        Allow from all
    </proxy>
    ProxyPass / http://192.168.1.4/
    ProxyPassReverse / http://192.168.1.4/
</VirtualHost>

注意,在上面的所有vhost定义中,我都删除了日志文件的选项。因此,如果应用到生产服务器,请将它们添加到每个vhost文件中。以上只是给你一个清晰的例子,说明它是如何工作的。我运行一个非常复杂的Apache设置,所以上面只是一个小的例子来帮助你。

现在回到问题的Ajax部分

在chrome中按Ctrl+Shift+I你会看到确切的应用程序被打破的地方,它会给你一些提示,(从不同于开发web应用程序的机器发出请求)另外,如果你可以查看apache日志,如果来自http://sample页面的ajx api的请求实际上到达了你的apache服务器,这将给你更多的提示,如果代理正确转发你的请求,在没有请求和应用程序发出请求的情况下,使用firefox中的一些工具(如live_http)发布HTTP标头,这样观察标头可以帮助您是否请求到达反向代理后面的服务器,还可以检查运行反向代理的服务器的日志,如果来自web的请求到达了它,如果请求到达了请求的URL是什么。这会给你一个提示,

和出于开发目的,在你的.conf文件中禁用重写规则一段时间来测试,一个一个地做。

这里的问题是浏览器试图保护您免受放置在某些网页上的随机javascript的攻击。如果它会让所有的javascript在相同的上下文中运行,你会失去你的Facebook会话cookie或其他一些数据给坏人。

在这种情况下,罪魁祸首可能是一些简单的东西,因为Chrome不认为'dev'是一个完全合格的域名,所以它将失败的同源测试。另一个原因可能是,有时你从app。somesite。dev获取东西有时你向dev发送请求

服务器不关心他们发送的是什么,你需要欺骗的是浏览器,让它相信所有的东西都来自同一个主机

    我将把hosts文件中的dev替换为dev.example.com 127.0.0.1
  1. 我将确保Apache代理的所有内容只引用dev.example.com,无论它来自哪个服务器
  2. 只在代码中使用dev.example.com

如果这些都失败了,你可以添加一个HTTP头'Access-Control-Allow-Origin: *'来允许任何来源,但我不会使用这个,除非只是在开发环境。

p。即使你从example.com:80得到javascript, javascript甚至不能调用example.com:443或javascript从example.com不能使xmlhttprequest到dev.example.com

在127.0.0.1,你的html代码应该是:

$.ajax({
    url: "http://127.0.0.1/a/w/currencies",
    type: "GET",
    dataType: "json",
    data: {
    },
    success: function(data){
        console.log(data);
    }
}); 

在127.0.0.1上,你的apache配置应该是:

...
<VirtualHost dev:8080>
            ...
            ProxyPass / https://app.somesite.com:5002/
            ProxyPassReverse / https://app.somesitecom:5002/
            ...
</VirtualHost>
在这种情况下,您的浏览器将不会跨域,因为您的url和ajax使用相同的域。但确切地说,ajax请求https://app.somesite.com:5002/,我不知道它是否是一个反向代理,但它似乎为我工作。有一个尝试:)

我将尝试同样的事情我自己很快,这就是我如何发现这个线程。

我想知道您在AJAX请求中使用的实际url是否错误。实际上,您正在连接到代理。它正在把你转发到8080端口地址。然后尝试直接向8080地址发出AJAX请求?相对链接可以使AJAX调用沿着相同的路径转发,以便javascript知道它是相同的来源。

另一种选择是使用PHP后端。这门在线课程的第7讲涵盖了AJAX,并用PHP做了一个例子来完全规避同源限制。http://academicearth.org/courses/building-dynamic-websites/

我刚发现这个,它似乎是一个更好的解决方案。http://darius.kruythoff.net/blog/2011/xss-with-apache/

相关内容

  • 没有找到相关文章

最新更新