【问题标题】:How do I make a function that returns the value of a local text file in JavaScript?如何在 JavaScript 中创建一个返回本地文本文件值的函数?
【发布时间】:2016-10-12 02:50:34
【问题描述】:

我只是在做一个小项目,这是我读取本地文本文件的代码:

function readTextFile(file)
{
    var rawFile = new XMLHttpRequest();
    rawFile.open("GET", file, false);
    rawFile.onreadystatechange = function ()
    {
        if(rawFile.readyState === 4)
        {
            if(rawFile.status === 200 || rawFile.status == 0)
            {
                var allText = rawFile.responseText;
                alert(allText);
            }
        }
    }
    rawFile.send(null);
    return allText;
}

我很确定我只是把退货放错地方了。有谁知道我应该把它放在哪里,或者可以在整体上做出更好的功能?

【问题讨论】:

  • XMLHttpRequest.prototype.onreadystatechange 异步返回结果,allText 可能未在return allText 中定义。另见Jquery load() only working in firefox?
  • 没关系...你在回调函数中定义了var allText,所以当你尝试返回它时它超出了范围
  • @guest271314 - 他正在做一个“同步”xhr
  • @JaromandaX 是的,试图在之前的评论中传达这一点,提到如何启动 chromium、带有标志的 chrome 以在file:protocole 请求文件
  • @guest271314 - 不,不是,如果您将false 作为第三个参数传递给.open - 当您使用var allText; 修复范围问题时,代码可以正常工作(同步) - 虽然它仍然无法在 Chrum 中工作,因为这是一个跨域请求的愚蠢概念

标签: javascript file text local


【解决方案1】:

不存在异步问题,您的代码的唯一问题是您在 onreadystatechange 回调函数的范围内声明了 allText

如果您在该函数之外声明此 var,它将正常工作

function readTextFile(file) {
    var rawFile = new XMLHttpRequest();
    var allText; // var declared in readTextFile scope
    rawFile.open("GET", file, false);
    rawFile.onreadystatechange = function () {
        if(rawFile.readyState === 4) {
            if(rawFile.status === 200 || rawFile.status == 0) {
                allText = rawFile.responseText;
            }
        }
    }
    rawFile.send(null);
    return allText; // here you can return the data filled in above
}

但是请注意,在大多数浏览器中,主线程中的同步 XMLHttpRequest 已被弃用 - 您应该学会接受异步代码。最简单(也是目前最跨浏览器)的方法是使用回调,例如

function readTextFile(file, callback) {
    var rawFile = new XMLHttpRequest();
    rawFile.open("GET", file, true); // make it asynchronous
    rawFile.onreadystatechange = function () {
        if(rawFile.readyState === 4) {
            if(rawFile.status === 200 || rawFile.status == 0) {
                callback(rawFile.responseText);
            }
        }
    }
    rawFile.send(null);
}

用法

readTextFile('someFile.txt', function(allText) {
    console.log(allText);
});

关于 CHROME 的说明

Chrome - 暂时没有特殊的命令行标志--allow-file-access-from-files - 无论如何都会失败,因为它会产生一个错误,指出“跨域请求仅对 http https ... etc" 协议有效 ... file:/// 不是这样的协议

但是,如果您使用 file:/// 打开文件,那么如何读取 file:/// 是跨域的???只有 Chrum 的开发者才能回答这个问题

【讨论】:

  • “Chrome 无论如何都会失败,” 这并不完全正确。可以使用XMLHttpRequest 使用铬标志以file: 协议请求文件
【解决方案2】:

注意,chromium,chr​​ome 默认不允许对file: 协议的请求。您可以启动 chromium,带有标志 --allow-file-access-from-files 的 chrome 以通过 file: 协议从本地文件系统请求文件。

您可以使用回调或Promise.then()readTextFile 返回.responseText 作为已实现Promise 对象的值。

function readTextFile(file) {
  return new Promise(function(resolve, reject) {
    var rawFile = new XMLHttpRequest();
    rawFile.open("GET", file, false);
    rawFile.onreadystatechange = function ()
    {
        if(rawFile.readyState === 4)
        {
            if(rawFile.status === 200 || rawFile.status == 0)
            {
                resolve(rawFile.responseText);
            }
        }
    }
    rawFile.onerror = reject;
    rawFile.send(null);
  })
}

readTextFile("file://path/to/file.txt")
.then(function(text) {
  // `text` : `rawFile.responseText`
  console.log(text);
  alert(allText);
})
// handle error
.catch(function(err) {
  console.log(err)
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-27
    • 2012-01-15
    • 2011-07-21
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多