如何将文本文件的内容加载到JavaScript变量中?

209
我有一个文本文件在我的web应用的根目录下:http://localhost/foo.txt 我想在javascript中将它加载到一个变量中... 在groovy中,我会这样做:
def fileContents = 'http://localhost/foo.txt'.toURL().text;
println fileContents;

我如何在JavaScript中获得类似的结果?
9个回答

166

XMLHttpRequest,即AJAX,不使用XML。

具体方法取决于您正在使用的JavaScript框架,但如果我们忽略互操作性问题,您的代码将类似于:

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

一般来说,XMLHttpRequest并非所有平台都可用,所以需要进行一些调整。再次强调,最好使用像jQuery这样的AJAX框架。

还需注意的是:只有当foo.txt在同一域名下才能正常工作。如果它在不同的域名下,同源策略将阻止你读取结果。


2
绕过同源策略的一种方法是使用JSONP,它也被jQuery支持(用于客户端部分)。 - OneWorld
8
在onreadystatechange内部,可以访问XMLHttpRequest对象的readystate属性(例如:client.readystate),以了解其状态。因为onreadystatechange事件会在加载、已加载等状态时触发,所以您必须在onreadystatechange内等待client.readystate == 4,然后才能使用client.responseText。请注意保持原意,使翻译更易懂。 - GameAlchemist
4
@GameAlchemist发现了你的好答案。我只想指出,在大多数浏览器中,readyState是驼峰式写法,所以代码应该像这样:if (client.readyState === 4){ } - snorpey
10
此外,您可以使用 client.onloadend 方法获取已完成的数据。 - worbel
4
答案应该被修改以包括检查 client.readyState 属性的值。在它被修改之前我会给它一个负面评价,因为人们不会去读评论来发现这个答案只是部分正确的。 - Armen Michaeli
显示剩余4条评论

89

4
是的,Fetch是一个(最近的)标准,而不是专有扩展。 - Laurent Caillette
2
到了2019年,fetch成为一种非常流行的技术。在所有现代浏览器(包括刚刚跟上步伐的Samsung Internet)中,这是最好的方式。 - Dave Everitt
一个紧凑且可工作的代码,Vic,谢谢你。为了实现错误处理,是否可以在您的代码中放置一些response.ok(或等效)?我对fetch不是很有经验,所以不知道确切的设置位置。 - Sopalajo de Arrierez
很棒的解决方案。即使对于完全的初学者来说,这也非常容易。在最后一步中存储在变量中而不是使用console.log,现在可以在任何地方使用。 - AveryFreeman
1
async 函数内,您可以执行 const text = await fetch(url).then($ => $.text()) 来展开回调函数。 - Carl Smith
显示剩余2条评论

89

这是我在 jQuery 中的实现方式:

jQuery.get('http://localhost/foo.txt', function(data) {
    alert(data);
});

1
似乎无法使用普通表格文本数据(http://docs.jquery.com/Specifying_the_Data_Type_for_AJAX_Requests)进行操作。 - pufferfish
10
需要注意的是,如果你在本地使用 file:// 进行测试,这种方法无法工作,例如:file:///example.com/foo.html 。Firefox 会报语法错误,而 Chrome 则会阻止它,因为它被视为跨域请求。 - Akronix
1
@pufferfish 如果您指定dataType参数,它将适用于普通数据,请参见api.jquery.com/jQuery.get/ - yvesonline
4
如果省略掉"http://..."这一部分,因为它与同一域名下,代码就可以正常工作了,例如:jQuery.get("foo.txt", ...) - yvesonline
1
@Akronix 有没有一种简单的方法在本地进行测试?我一直收到跨域请求错误。 - ahuff44
显示剩余3条评论

43
如果您只需要从文本文件中获取一个常量字符串,可以将其包含在JavaScript中:

// This becomes the content of your foo.txt file
let text = `
My test text goes here!
`;
<script src="foo.txt"></script>
<script>
  console.log(text);
</script>

文件中读取的字符串在加载后可以被JavaScript访问。`(键盘左上角的符号)字符开始和结束模板字面量,可以在文本块中使用 " 和 ' 字符。

这种方法在尝试本地加载文件时效果很好,因为Chrome不允许对带有 file:// 方案的URL进行AJAX请求。


1
这将是一个非常流畅的解决方案。但是,模板字面量在IE11中不受支持,并且“let”变量在函数块内部时会超出范围,因此此实现充满了危险,请小心。 - Neville
1
目前,即使微软也准备淘汰IE,可以通过将其设置为返回字符串的函数来简化范围,而不是使用“let”设置变量。 - Paul Slocum

24

2020更新:使用async/await与Fetch

const response = await fetch('http://localhost/foo.txt');
const data = await response.text();
console.log(data);

请注意,await 只能在 async 函数中使用。一个更长的示例可能是:

async function loadFileAndPrintToConsole(url) {
  try {
    const response = await fetch(url);
    const data = await response.text();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

loadFileAndPrintToConsole('https://threejsfundamentals.org/LICENSE');


1
好的,除了源需要有CORS之外,一切都很好,但这不一定适用于许多源。 - Lakshaya U.
1
这就像是问:“你怎么从银行取钱?”回答:“进银行写支票换现金。”你说:“这都没问题,但如果我想从别人的账户里取钱,那就需要授权委托书,而我并没有大多数账户的授权委托书。”CORS 的存在是有原因的。服务器决定你是否有权限读取资源。 - gman
是的。但是出于非跨源请求考虑,AJAX更好。 - Lakshaya U.
1
XMLHttpRequest有相同的限制。 - gman

8
这应该适用于几乎所有的浏览器:
var xhr=new XMLHttpRequest();
xhr.open("GET","https://12Me21.github.io/test.txt");
xhr.onload=function(){
    console.log(xhr.responseText);
}
xhr.send();

此外,还有新的 Fetch API:
fetch("https://12Me21.github.io/test.txt")
.then( response => response.text() )
.then( text => console.log(text) )

8

需要记住的一件事是Javascript运行在客户端而不是服务器上。你不能真正地用Javascript“加载一个文件”从服务器上。实际上Javascript向服务器发送一个请求,服务器则返回被请求文件的内容。那么Javascript是如何接收这些内容的呢?这就是回调函数的作用。在Edward的情况下,就是

    client.onreadystatechange = function() {

在丹伯的情况下,它是这样的。
 function(data) {

每当数据到达时,都会调用此函数。jQuery版本隐式使用Ajax,它通过将该代码封装在库中使编码更加容易。


2
当使用jQuery时,可以使用jQuery.get代替,例如:
jQuery.get("foo.txt", undefined, function(data) {
    alert(data);
}, "html").done(function() {
    alert("second success");
}).fail(function(jqXHR, textStatus) {
    alert(textStatus);
}).always(function() {
    alert("finished");
});

您可以使用 .load,这将为您提供更加简洁的形式:
$("#myelement").load("foo.txt");

.load 还提供了加载部分页面的选项,这很方便,请参见api.jquery.com/load/


1
<!DOCTYPE html> <html> <body id="ibody">
<script>

fetch('http://localhost/myFolder/myFile.txt')
.then(response => response.text())
.then((data) => {ibody.innerHTML= data})

// data is the variable you want

</script> </body>  </html>

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