12

需要开发一个同时高度依赖 API 但又不能与 API 本身驻留在同一域中的 Web 应用程序,在发出异步 HTTP 请求时绕过“同源策略”非常棘手(阿贾克斯)。有一次,有人建议我在我的计算机(运行 Windows 7)上安装 WAMP,并使用 Apache 配置反向代理。同一个人在告诉我为名为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.错误。

$.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 ”。鉴于我缺乏经验,这都没有多大意义。

4

4 回答 4

11

您有一个具有公共 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

每个站点的虚拟主机定义如下

/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 文件中。以上只是为您提供一个明确的示例,说明它是如何工作的。我运行了一个非常复杂的 Apache 设置,所以上面只是一个帮助你的小例子。

现在来到 Ajax 你的问题的一部分

在 chrome 中按 Ctrl+Shift+I 你会看到应用程序到底在哪里坏了,它会给你一些线索,(从与你正在开发 Web 应用程序的机器不同的机器发出请求)如果你可以看看如果请求来自 apache 日志http://sample具有 ajx api 的页面实际上已到达您的 apache 服务器,这将为您提供更多提示,如果代理正确转发您的请求,请使用 firefox 中的某些工具(如 live_http)在没有请求的情况下发布 HTTP HEADERS请求是由应用程序发出的,如果请求到达反向代理后面的服务器,观察标头可以为您提供帮助,还检查运行反向代理的服务器的日志,如果来自 Web 的请求到达它,以及请求是否到达到达了所请求的 URL。这会给你一个线索,

并且出于开发目的,在您的 .conf 文件中禁用重写规则一段时间以进行测试,一一进行。

于 2013-01-06T20:11:35.757 回答
1

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

在这种情况下,罪魁祸首可能很简单,因为 Chrome 不认为 'dev' 是完全合格的域名,因此它将无法通过同源测试。其他原因可能是在某些时候您从 app.somesite.dev 获取内容,并且在某些时候您向“dev”发送请求

服务器不在乎他们发送什么,您需要欺骗浏览器以相信所有内容都来自同一主机

  1. 我会用 dev.example.com 127.0.0.1 替换主机文件中的“dev”
  2. 我会确保来自 Apache 代理的所有内容都只引用 dev.example.com,无论它来自哪个服务器
  3. 仅在您的代码中使用 dev.example.com

如果一切都失败了,您可以添加一个 HTTP 标头 'Access-Control-Allow-Origin: *' 以允许任何来源,但我不会使用它,除非仅在开发环境中使用。

PS。即使您从 example.com:80 获取 javascript,javascript 甚至无法调用 example.com:443 或 example.com 的 javascript 也无法向 dev.example.com 发出 xmlhttprequests

于 2013-11-10T20:29:55.283 回答
0

在 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,但它似乎对我有用。试试 :)

于 2016-12-09T13:43:35.300 回答
-1

我很快就会自己尝试同样的事情,这就是我找到这个线程的方式。

我想知道您在 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/

于 2013-10-24T14:23:30.393 回答