更新Ajax请求上的整个页面

2022-08-30 14:52:30

我有一个 AJAX 请求,可能有两种可能的结果:

  1. 服务器响应一条消息,我应该将其放在<div>
  2. 服务器使用HTML页面进行响应,在这种情况下,我需要用新页面替换当前页面并更改地址(客户端在请求之前知道地址)。

如果我有需要处理这两种情况的 AJAX 请求,解决方案是什么?

 url = "http://example.com"
 ajax.request(callback)

 function callback(response) {
     if (case2(response)) {
           history.pushState({}, "New page", url);
           document.innerHTML = response
     } else {
            updateDiv(response)
     }
 }

我对实现第一个分支的正确方法感兴趣,或者服务器是否可以以某种方式编写一个标头,使浏览器像通常的HTTP响应一样处理响应并更新页面位置和内容,例如使用给定内容重定向。

我知道服务器可以返回链接而不是页面,但在这种情况下,客户端上需要一个额外的阶段 - 重定向,然后在服务器上填充新页面。


答案 1

坦率地说,我认为这种方法基本上是被设计打破的。你不应该在那个地方做出那个决定。例如,ajax 响应只能发出信号,表明应该加载一个全新的页面,然后在对新 URL 的第二个(非 ajax)请求中生成新内容。

如果你被迫采取你已经走的方式,并且如果响应内容不是很大,你可以尝试Javascript-URI。基本上,格式的URI将加载一个新页面,该字符串是其源代码。因此,如果已经是一个字符串,只需分配到就足够了。也许你必须事先做一些逃避。我不知道,这种方法的跨浏览器兼容性如何。javascript:"string"responsejavascript:responsewindow.location.href

<a href="javascript:response">load</a>

也是可能的。

其变体不是使用变量名称,而是使用实际的字符串数据来构建 URL。喜欢

function source2url(src) {
    // make valid javascript string from source text
    var esc1 = src
        .replace(/\\/g, '\\\\')
        .replace(/\'/g, '\\\'')
        .replace(/\x0A/g, '\\x0A')
        .replace(/\x0D/g, '\\x0D');

    // make valid url from that
    return "javascript:'" + encodeURIComponent(esc1) + "'";
}

window.location.href = source2url(response);

当然,这将生成相当大的 URI。而且,地址栏中始终会有 Javascript-URI。

更新

类似的方法是在数据 URI 中使用 base64 编码。维基百科条目解释了它是如何工作的,包括一个javascript示例。但是,您必须以某种方式对内容进行base64编码。(注意:可以使用带或不带 base64 编码的数据 URI。您必须了解是什么为您的特定内容提供了更短的URI。


答案 2

我曾经遇到过类似的问题。返回了完整的错误页,而不是简单的 HTML 代码段。我们最终通过更改逻辑来解决此问题,但这是我发现的解决方案之一:

document.open();
document.write(responseText);
document.close();

我们放弃这一点的原因是IE上存在一些问题。我没有花时间调查原因,但它在尝试写入字符串时抛出了“拒绝访问”异常。我认为有一些标签混淆了IE,或者可能是条件评论,我不确定。(当我使用一些简单的页面时,它起作用了...)<meta>

底线是:你不应该这样做,但如果没有其他你可以做的事情(比如返回一个url字符串),上面的代码可能会起作用。