![反向代理和 AJAX](https://linux22.com/image/489392/%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E5%92%8C%20AJAX.png)
我们的一个客户正在使用 IBM/Tivoli WebSEAL,这是他们一些内部用户的反向代理服务器。我们的 Web 应用程序 (ASP.NET 2.0) 是一个相当简单的 Web/数据库应用程序。
目前,使用 WebSEAL 代理的客户端用户在使用 .NET 第三方控件时遇到了问题。未使用代理的用户则不会遇到任何问题。第三方控件只不过是一个 AJAX 动态树,每次单击都会请求每个叶子的所有节点。
现在我们的客户声称,一旦用户单击控件中的节点,控件本身就会冻结,以至于他们看不到任何内容。用户看到“正在加载...”消息出现,但之后没有新的活动。他们必须离开页面并返回原始页面才能查看新节点。
我以前从未使用过反向代理,所以我在 Google 上搜索了很多关于这个主题的内容,甚至找到了一个文章在 SF 上。IBM/Tivoli 提到这个问题之前,但他们提到的几乎全部都是这样。虽然 IBM 文档非常有用,但我们所有的 AJAX 都来自第三方控件。我尝试使用 Firebug 进行故障排除,但由于没有使用反向代理,我无法真正复制问题。
我的问题是:有人有使用反向代理和 AJAX 网站问题的经验吗?我该如何证明确切的问题是什么?目前我们正在协商远程访问,因此在很大程度上假设我将可以访问使用 WebSEAL 代理的机器。
PS 我意识到这个问题可能与 StackOverFlow/ServerFault 管辖权之争有关,但我正试图从系统角度进行调查。我没有使用反向代理的经验(也不清楚它的好处),对转发代理也了解不多。
答案1
在获得客户网站的访问权限(通过 WebSEAL)并构建测试用例后,我们得到了答案。根据IBM 有关 AJAX 和 WebSEAL 的文档,在非常在 Junction cookies 部分的末尾有一段内容如下:
潜在解决方案。
如果 AJAX 请求的响应不以 HTML 形式呈现,则不应使用内容类型“text/html”发送响应。应使用更合适的内容类型,例如“text/plain”。WebSEAL 不会将连接 cookie 代码添加到内容类型不是“text/html”的响应
对于我们的 ASP.NET 应用程序,这是一个添加到使用控件的 Page_Load 事件中的简单条件。
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear();
Response.ContentType = (Page.IsCallback) ? "text/plain" : "text/html";
//does same thing as line above
//if (Page.IsCallback)
// Response.ContentType = "text/plain";
//else
// Response.ContentType = "text/html";
}
我确信其他语言(PHP、JSP、RoR 等)都有改变内容类型的方法。就 ASP.NET 而言,我不确定是否有更好的生命周期事件方法来放置它(PreInit?),但这是解决 AJAX 和 IBM WebSEAL 反向代理连接 cookie 这一特定问题的有效方法。
答案2
这可能取决于您的应用程序如何工作 - 如果它在某些地方使用绝对 URI,而这些 URI 指向代理后面的用户无法访问的东西 - 这可能是您的问题。
假设您有代理 P、服务器 S 和用户。服务器有一个给定的主机名(可能更多),其中一个可能与 Web 服务器(我们称之为 server1)相关联。用户可能能够或不能直接向 server1 发出请求。很有可能,使用反向代理,他们必须向代理发出请求,然后代理会查询您的服务器。
他们看http://P/YourAppHere- 虽然应用程序实际上位于http://server1/YourAppHere(或其他任意路径)。如果您的应用程序配置为直接引用http://server1/YourAppHere/foo.asp,并且代理不会接收并修改发送给用户的代码,以便它指向http://P/YourAppHere/foo.asp,否则会破坏功能。
有点像瞎猜,但我在 Sharepoint 中遇到了类似的问题。
答案3
对于 WebSEAL 和其他反向代理,最好的办法是仅使用相对 URL。AJAX 和其他 Web 2.0 编码方法的最大问题是,它们喜欢将信息发送回客户端,以便客户端在客户端创建绝对 URL。如果需要,反向代理无法过滤这些信息。例如,返回的形式为 backendserver.com8443https
URL=协议+“://”+主机+端口+“/somebackendURL/item.html”
绝对 URL 只有在通过反向代理时才会被过滤,如下所示
https://backend.server.com:8443/ 这与连接服务器相匹配。
即使您没有像这样编码,连接 cookie 也会产生大量问题。
如果您的 html 页面在脚本标记内调用了 .js 文件,那么如果 .js 文件获得了添加到其中的 cookie,您就会得到嵌套的脚本标记,并且浏览器会出错。
例如 test.html 是 hello
那么这是对 WebSEAL 的 2 个请求。如果它们通过设置了连接 cookie 的连接,最终页面看起来类似于。
设置 cookie IV_JCT=junctionname
> 你好