使用Javascript加载非HTML内容,是否可行?

3
以下是翻译的结果:

情境描述:

我想使用JavaScript进行一些HTTP API调用,并在浏览器中加载响应。请求可能是GETPOSTPUTDELETE,而返回的响应可以是任何类型的内容 - 可能是HTML、JSON、XML或图像、文档、二进制内容或其他任何内容。我希望浏览器以与加载新页面相同的方式处理响应。

问题是我看不到任何方法来加载接收到的任意内容。

显然,可以将内容加载到DOM中,但这只允许我处理HTML。(和潜在地嵌入一些媒体类型,例如图像等)我没有看到任何明显的方法来处理嵌入式响应类型,例如JSON和XML,而不必为如何将每种类型呈现为HTML构造特殊情况。

我曾考虑过是否有一些绕过方法,涉及框架或更改window.location以加载内容,但我看不到任何使其工作的方法。

是否有可能做到我要寻找的事情,或者您能否提出任何优雅的解决方案?

编辑:

为了更好地了解背景 - 这是关于API浏览器的一些工作。我对GETPOST需要做的事情没有问题 - 难点在于PUTDELETE,因为我无法直接使用HTML支持它们。目前,该实现使用一些服务器端技巧和表单上的隐藏的_method字段,允许将POST请求重载为PUT/DELETE/OPTIONS/等等,但理想情况下,我希望将该逻辑从服务器端移除,并使用JavaScript执行相应操作。

现在我认为这实际上是不可能的,但我希望有人能证明我错了,或者找到一个优雅的解决方案。


其中一种选择是将资源(文件)作为链接提供,当用户点击时,文件会在客户端上下载。任何客户端上的支持软件/应用程序都可以运行/打开该文件。这个解决方案不在浏览器内部。 - Sandeep G B
那行不通,因为它只允许我执行“GET”请求。 - Tom Christie
1
我希望响应能够以与浏览器加载新页面完全相同的方式由浏览器处理。然后加载一个新页面。您的浏览器已经具有这个功能。 - Lightness Races in Orbit
这意味着它将会发起一个GET请求(或者对于POST表单来说是POST),这对我想要的不够。我还想能够在响应PUTDELETE请求时加载新页面。 - Tom Christie
3个回答

1

我想知道你是否可以打开一个新窗口或创建一个iframe,其中传递给窗口或iframe的URL不是Web上资源的绝对URL,而是data uri。您需要嗅探响应的mime类型,然后对响应的正文进行编码。

不知道它是否有效,但如果您成功实现了它,我会很感兴趣听到您的经验。

其他要探索的内容:BlobBuilder(HTML5功能)和创建“无源”iframe(其中src只是about:blank)具有自定义mime类型,然后使用document.write将代码写入iframe文档中(AppleOfMyIframe中的一些代码可能会有用)。


使用数据URI似乎是最有前途的选择。(可能使用BlobBuilder构建这些URI。) - Tom Christie
1
http://www.aminus.net/wiki/Okapi 使用一个 iframe,并允许您选择 document.write、body.innerHTML 或数据 URL 作为 document.location,因为每种方法都有其优缺点。您可以考虑给您的用户提供相同的选择。 - fumanchu
有趣的项目! - Tom Christie

1

我认为数据URI可能可行,但最终我觉得你可能会在其他地方引入复杂性,以消除一点点服务器端解析(你的POST参数)。

如果你不介意使用中间GET请求来加载响应,那么你可以使用AJAX和重定向组合,但我猜你可能会介意,所以这不可行。

既然你不想使用AJAX并插入到DOM中,我认为你目前的表单字段是最优雅的,或者至少是最健壮的解决方案。没有与iframe、新窗口或类似的东西纠缠,一个请求产生一个响应,代价是可能需要将POST重新解释为服务器端的其他内容。

我想不出比你目前采用的更好的解决方案了。


是的,我认为我已经得出结论,没有任何干净的方法来做到这一点。我不介意插入DOM,但除非有一种通用的方式来插入任意内容和任意MIME类型,否则这是不可行的。 - Tom Christie
如果服务器能够返回一个指向资源的URL响应,而不是实际返回资源,那么浏览器可以简单地打开一个新窗口或iframe,并使用该URL。这确实会削弱您的REST API的优雅性,但可能是实用的。如果数据是私有的,则需要混淆URL。也许只有在请求中发送了特定的自定义标头时才会发生这种行为。 - Prem
@Premasagar “如果服务器能够返回一个指向资源的URL响应,而不是实际返回资源” - 这就违背了我所要做的目的。我试图消除服务器端的欺骗,并使“使用PUT发送表单”的行为完全在客户端上进行。 - Tom Christie
当然可以。只要你能做到 :) - Prem

0

如您所知,表单只允许进行POST和GET HTTP请求。要使用JavaScript执行PUT和DELETE操作的唯一方法是通过AJAX(XMLHttpRequest),但这不是您想要的,因为您特别要求在每个HTTP API调用后刷新页面并在浏览器上显示原始响应(可以是XML或JSON或其他任何格式)。

但是实际上,如果您所尝试的事情就像下面这么简单:

  1. 使用JavaScript进行HTTP API调用。
  2. 在GET/POST时加载包含原始数据的XML或JSON响应(除了解析它们并将其附加到DOM之外)

那么...我认为解决方案不应该比重定向更花哨:

<html>
<head>
   <script type="text/javascript">
       var url = //insert your url here
       var a = document.getElementsByTagName[](0);
       a.addEventListener("click", callAPI, false);

       function callAPI(){
           location.href=url;
       } 
   </script>
</head>
<body>
   <a href="#request">Click here to make HTTP call</a>
</body>
</html>

您点击该链接,然后重定向到包含XML/JSON的URL。这将显示响应,其中显示了嵌入到浏览器上显示的HTML中的原始数据。

如果这就是您要问的内容,请告诉我。希望能帮到您。如果您想了解更多关于JavaScript上的HTTP restful知识,可以尝试阅读这篇文章


我认为你已经基本理解我的问题了。但问题在于,虽然我可以轻松地触发任何类型的 AJAX 调用,但使用 location.href=url 加载响应时只会进行 GET 请求。 - Tom Christie
换句话说,该链接文章展示了如何在链接或表单提交的响应中触发AJAX请求,但没有展示任何将响应作为新页面加载的方法。(与将其转换为HTML并插入到DOM中不同。) - Tom Christie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接