[英]How to correctly configure a reverse proxy with Apache, to be used for cross-domain AJAX?
需要开发一个 Web 应用程序,该应用程序同时高度依赖 API 但同时不能与 API 本身驻留在同一域中,在发出异步 HTTP 请求时绕过“同源策略”非常棘手(阿贾克斯)。 有一次,我被建议在我的计算机上安装 WAMP(运行 Windows 7)并使用 Apache 配置反向代理。 在告诉我在c:\\windows\\system32\\drivers\\etc\\hosts
的文件中为名为dev的 IP 127.0.0.1 创建别名之后,同一个人给了我下面添加到httpd.conf
文件的 Apache 指令c:\\windows\\system32\\drivers\\etc\\hosts
(我做了):
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
。
不幸的是,对同一 URL 的 AJAX 请求(代码如下)使 Chrome 给我XMLHttpRequest cannot load http://dev:8080/a/w/currencies. Origin http://dev is not allowed by Access-Control-Allow-Origin.
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 获取文件并 ajaxing 到 dev:8080 ”。 鉴于我的经验不足,这都没有多大意义。
您拥有一台带有公共 IP 的服务器,并且 apache 正在其上运行。现在您想在 LAN 上托管您的应用程序,并希望它们可以在 Internet 上访问,重要的是这些应用程序仍在 LAN 上的机器上运行。
|--------------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 的系统网站的定义是在
/etc/apache2/sites-enabled/*.conf
其中 *conf 对应于
internal1.conf internal2.conf internal3.conf internal4.conf
每个站点的 vhost 定义如下
/etc/apache2/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/apache2/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/apache2/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/apache2/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 应用程序的机器不同的机器发出请求),如果您也可以查看如果来自具有 ajx api 的http://sample
页面的请求实际上到达了您的 apache 服务器,这会给您更多提示,如果代理正确转发您的请求,请使用 firefox 中的一些工具发布 HTTP HEADERS,例如 live_http没有请求时的条件和应用程序发出请求时的条件,如果请求到达反向代理后面的服务器,则观察标头可以帮助您,如果请求到达反向代理服务器,请检查运行反向代理的服务器的日志来自 web 的请求是否到达了它,如果请求到达了请求的 URL。这会给你一个线索,
并且出于开发目的,在您的 .conf 文件中禁用重写规则一段时间以进行测试,一一进行。
这里的问题是浏览器试图保护您免受放置在某个网页上的随机 javascript 的攻击。 如果它让所有 javascript 在相同的上下文中运行,你就会失去 Facebook 会话 cookie 或其他一些数据给坏人。
在这种情况下,罪魁祸首可能很简单,因为 Chrome 不认为“dev”是完全合格的域名,因此它将无法通过同源测试。 其他原因可能是在某些时候你从 app.somesite.dev 获取东西,在某些时候你向“dev”发送请求
服务器不在乎他们发送什么,它是你需要愚弄的浏览器相信一切都来自同一个主机
如果所有其他方法都失败了,您可以添加一个 HTTP 标头 'Access-Control-Allow-Origin: *' 以允许任何来源,但除了在开发环境中之外,我不会使用它。
附注。 即使您从 example.com:80 获得 javascript,该 javascript 甚至无法调用 example.com:443 或来自 example.com 的 javascript 也无法向 dev.example.com 发出 xmlhttprequests
在 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 conf 应该是:
...
<VirtualHost dev:8080>
...
ProxyPass / https://app.somesite.com:5002/
ProxyPassReverse / https://app.somesitecom:5002/
...
</VirtualHost>
在这种情况下,你的浏览器不会跨域,因为你的url和ajax使用的是同一个域。但确切地说,ajax请求https://app.somesite.com:5002/ ,不知道是不是反向-proxy ,但它似乎对我有用。 试试 :)
我很快就会自己尝试同样的事情,这就是我发现这个线程的方式。
我想知道您在 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/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.