【问题标题】:Javascript - Include contents of .txt file on page load *without* ajax?Javascript - 在页面加载时包含 .txt 文件的内容 * 没有 * ajax?
【发布时间】:2016-09-19 09:37:06
【问题描述】:

瘦子

我很清楚 JS 需要 AJAX(或一些同步/异步调用)到 get the contents of a file页面加载后

(来自上一个链接)

var client = new XMLHttpRequest();
client.open('GET', '/foo.txt');
client.onreadystatechange = function() {
  alert(client.responseText);
}
client.send();

浏览器不允许直接访问文件。这是出于安全原因,缓解 XSS 攻击等。

但是有没有办法将它包含在页面加载中...而不包含它到标记中?

我正在使用几个客户端模板(对客户端与服务器端的争论不感兴趣)。目前,在页面加载时包含它们的唯一方法,无需额外调用服务器,就是将内容放入自定义类型的 script 标记中:

<script id="t1" type="x-some-template">
    ... contents of template
<script>

然后以某种方式引用脚本块的内容:

var templateContents = $('#t1').html();

但是如果模板很长,它会混淆标记(假设用户正在查看源代码)。 这完全是美学和吹毛求疵,不会影响任何东西的运作,但是有没有什么鬼鬼祟祟的方法来包含模板而不让它们出现在标记中?

到目前为止...

我尝试将模板放入它自己的 .js 文件中,并以相同的方式包含它:

<script id="t1" type="x-some-template" src="t1.js"><script>

但是没有办法引用内容,因为它永远不会被浏览器加载。

(来自javascript.info

如果您将不支持的值放入类型中,例如,内容将被忽略。这是使用的技巧 添加未呈现到页面的数据。

但是如果你输入一个已知的类型:

<script id="t1" type="text/javascript" src="t1.js"><script>

会抛出错误,因为文件的内容不在正确的 JS 中。

其他解决方案可能是将模板内容分配给 JS 变量,并包括外部文件,然后引用所述变量:

// t1.js

var temp = `... contents of template... `;

// page.html

var templateContents = temp;

但即使使用template literal,它也可能是一场噩梦,包括复杂的模板。然后你会遇到将每个模板分配给不同的变量并跟踪它们的问题。头痛比比皆是。如果您可以将每个模板分配给一个标准变量,然后根据包含它的脚本块引用它们,这个问题将会稍微缓解......

var templateContents1 = $('#t1').temp;
var templateContents2 = $('#t2').temp; // Or something like this...
... 

但这是不行的。

我搜索了高低,但我遇到的只是无尽的 AJAX 和 HTML Imports,其中有 awful support

最后,问题

有没有人偶然发现了一个漂亮的方法来做到这一点?并以独立于浏览器(即普遍支持)的方式?我想远离任何加载后的服务器调用(即 AJAX)。

使用内容加载页面,并持续使用它。

对潜在解决方案的思考

美化标记的唯一方法(我能想出的)是使用当前工作的方法,然后完全删除脚本块:

var templateContents = $('#t1').html();
$('#t1').remove(); // Or similar

但这不是一个很好的解决方案,因为如果 JS 决定在 templateContents 上进行垃圾收集,那么内容将不再可用,并且您必须重新加载模板。

我不太喜欢 server/.htaccess 的东西,但也许我可以修改 .htaccess(或类似的)以将自定义类型脚本作为纯文本读取,然后它会保留在内存中以用于 as-需要依据吗?

天哪,如果...的话肯定会膨胀的。

理想情况与我上面描述的类似,纯模板内容位于单独的文件中(未分配给变量)...

// t1.js

... all the contents of the template...

然后将它包含在一个漂亮的单行中......

// page.html

<script id="t1" type="whatever-works" src="t1.js"></script>

并以同样简单漂亮的线条引用模板内容...

var templateContents = $('#t1').someTextAccessMethod();

有什么想法吗?

【问题讨论】:

  • 感谢您阅读全文!下一个很长的,我会在最后输入一个促销代码,供您下次在线购买冬季轮胎之类的东西。
  • 冬季轮胎ftw!
  • 您是否尝试过使用 localStorage...将内容存储到变量中然后在页面加载时获取它?
  • 你可以尝试使用 iframe。
  • @jcubic iframe 是一个更糟糕的选择。内容仍然显示在标记中(实际上更长,因为它会自动插入一大堆额外的标记),然后还需要我将 css 添加到 iframe 以隐藏它。

标签: javascript html ajax templates


【解决方案1】:

你可以试试这个。

这正是我所做的。

main.html

<!DOCTYPE HTML>
<html>

<head>
   <title>load txt</title>
</head>   
<body>
   <script type="text/javascript" src="test.js" type="application/json">
   </script>
   <script>
       document.write(a.data);
   </script>
</body>

</html>

还有 test.js 文件。

var a = {
    "data" : "All the content of .txt file here with proper escape sequence and other formatting stuff"
  }

现在,解释。

您可以将所有数据放在一个对象的txt文件中。将该对象保存在变量和单独的文件中。您可以在初始页面加载期间使用脚本标记来加载该文件。

使用 type="application/json" 阻止浏览器对对象的内容进行任何检查。

文件的扩展名可以是您想要的任何。 因为浏览器只检查正在下载的脚本类型。

一旦你加载了包含在对象中的 txt 文件,你可以执行JSON.stringify,将其加载到localStorage,然后从 html 中删除 script 标记。

在此之后,即使您关闭网站并重新打开它也可以访问它。而且您不必在服务器端或客户端进行任何修改。

【讨论】:

  • 这与我在问题中列出的情况相同:Other solutions could be assigning the template content to a JS variable...。重新阅读我的问题,你会看到它。如果我包含两个模板(或十个或 100 个),那么它们都必须以不同的方式命名(var a = ...var b = ... 等等)。不是解决办法,不管加type="application/json"
  • 哦,我现在明白了。很抱歉,我想不出任何其他方式来做到这一点。
【解决方案2】:

我看到您将内容放在&lt;script&gt; 标记上没有问题,只是它会使您的标记/视图源变脏。那么为什么不巧妙地将您的文件内容倒入外部 JS 文件(将其托管在某处/本地),然后在您的项目中调用该外部脚本,例如:

<script type="text/html" src="http://yourdomain.com/contents_of_template.js">
    var t1 = "<div> template contents here </div>"
</script> 

基本上这样你会得到内容,同时文件的内容不能在你的viewsource上看到,因为它是另一个外部JS文件的一部分。让我知道这对您是否有意义。

您还可以探索诸如窗口localStorageFileAPI 之类的选项来读取和写入文件,但同样,两者都需要通过某种方式通过 AJAX 来读取内容。

【讨论】:

  • 如果我做外部文件,难道我还必须将每个模板分配给一个唯一变量(即var t1 = '... long template string';)吗?我想 a) 将每个模板保存在自己的文件中(可能不是 .js 扩展名),b) 避免将模板分配给变量。我将如何使用您详细介绍的方法,同时将模板文件保留为原始模板(即&lt;header&gt;{{some_var}}&lt;/header&gt; - 任何地方都没有 JS)
  • 那么您要做的就是在外部contents_of_template.js 中分配一个变量。然后,您可以在 jquery 中的任何位置使用该变量。 var t1 = "&lt;div&gt; template contents here &lt;/div&gt;"。还将&lt;script&gt; 标签类型更改为text/html。更新了答案
猜你喜欢
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
  • 2016-03-13
  • 1970-01-01
相关资源
最近更新 更多