在JavaScript中打开本地文件

在JavaScript中打开本地文件,javascript,ajax,Javascript,Ajax,我是JavaScript新手。我找到了一个使用javascript打开本地文件的示例。在谷歌搜索之后,我可以将我的设置为允许读取本地文件,然后我就可以运行这个示例了。但是,我想返回字符串allText,稍后在脚本中使用它。但是字符串在readTextFile()之外变成undefined 还有一个类似的问题。它似乎与AJAX的异步特性有关。我现在几乎听不懂这些行话。我只是不明白为什么在这篇文章中,XMLHttpRequest.open()的第三个参数设置为true 无论如何,下面是我当前的代码。

我是JavaScript新手。我找到了一个使用javascript打开本地文件的示例。在谷歌搜索之后,我可以将我的设置为允许读取本地文件,然后我就可以运行这个示例了。但是,我想返回字符串
allText
,稍后在脚本中使用它。但是字符串在
readTextFile()之外变成
undefined

还有一个类似的问题。它似乎与AJAX的异步特性有关。我现在几乎听不懂这些行话。我只是不明白为什么在这篇文章中,
XMLHttpRequest.open()
的第三个参数设置为
true

无论如何,下面是我当前的代码。我想使用
allText
外部函数
readTextFile()


函数readTextFile(文件)
{   
var-allText;
var rawFile=new XMLHttpRequest();
打开(“获取”,文件,错误);
rawFile.onreadystatechange=函数()
{
if(rawFile.readyState==4)
{
if(rawFile.status==200 | | rawFile.status==0)
{
var allText=rawFile.responseText;
警报(所有文本);
}
}
}
rawFile.send(空);
return allText;//我认为这是出错的部分
}
t=readTextFile(“foo.file”);
document.write(t)//打印“未定义”而不是正确答案

这实际上很可能是一个范围问题。因为您是异步设置allText,所以函数返回后不能立即使用。此外,您正在重新初始化函数中的allText,这会影响返回的范围

rawFile.onreadystatechange
在函数返回后执行。您可以将执行移到XHR回调中,也可以将函数包装在承诺中,这仍然需要您稍微修改控制流

移动
文档。写入

<!DOCTYPE html>
<html>
    <script>
        function readTextFile(file)
        {   
            var allText;
            var rawFile = new XMLHttpRequest();
            rawFile.open("GET", file);
            rawFile.onreadystatechange = function ()
            {
                if(rawFile.readyState === 4)
                {
                    if(rawFile.status === 200 || rawFile.status == 0)
                    {
                        allText = rawFile.responseText;
                        document.write(allText);
                    }
                }
            }
            rawFile.send(null);
        }

        readTextFile("foo.file");

    </script>
</html>
function readTextFile( file ) {
  return new Promise( function ( fulfill, reject ) {

    var allText;
    var rawFile = new XMLHttpRequest();
    rawFile.open( "GET", file );
    rawFile.onreadystatechange = function () {
      if ( rawFile.readyState === 4 ) {
        if ( rawFile.status === 200 || rawFile.status == 0 ) {
          fulfill( rawFile.responseText )
        }
      }
    }
    rawFile.send( null );
  } );
}
readTextFile( "foo.file" )
  .then( function ( t ) {
    document.write( t );
  } );
这两种方法都将确保在XHR请求返回allText之前,脚本不会尝试使用allText


尽管如前所述,XHR请求是同步的,范围问题的性质与我最初假设的不同。问题在于重新定义函数中的变量,导致返回的变量未定义

您要声明两次
allText
(这使得两个变量具有相同的名称但作用域不同),请删除变量前面的第二个
var
关键字。祝JavaScript好运@BrandonAnzaldi虽然我不完全理解你的担忧,但这个脚本现在可以运行了,克里斯,没问题@BrandonAnzaldi是的,我知道同步Ajax请求是一种不好的做法,但他正在学习基本知识,我认为更好的解决方案是这样做@BrandonAnzaldi的方法现在应该是正确的@Chris.)希望我能提供帮助。实际上,
allText
正在同步设置,阻止主线程。。。在
rawFile.onreadystatechange
完成设置后,它完全可以访问!我的错。我最初没有注意到XHR请求上的async的
false
标志。信用在信用到期的地方,你有正确的答案:)没问题:)。。顺便说一句,地狱真的是一个地狱hell@both对不起,我刚才发了一个愚蠢的问题。正如圣地亚哥所提到的,这实际上只是一个语法问题。在调试过程中,我被所有的行话弄得不知所措。还有,有没有javascript IDE可以帮助我避免这种错误?@Chris这根本不是一个愚蠢的问题!一开始我甚至没有注意到核心问题。过梁应该可以帮助您避免这些问题。无论您使用的是什么编辑器,都可能有一个linter插件:)ES Lint或JSHint是您脑海中出现的两个linter,它将为您提供风格和语法提示,并帮助您捕捉可能遗漏的问题。:)
function readTextFile( file ) {
  return new Promise( function ( fulfill, reject ) {

    var allText;
    var rawFile = new XMLHttpRequest();
    rawFile.open( "GET", file );
    rawFile.onreadystatechange = function () {
      if ( rawFile.readyState === 4 ) {
        if ( rawFile.status === 200 || rawFile.status == 0 ) {
          fulfill( rawFile.responseText )
        }
      }
    }
    rawFile.send( null );
  } );
}
readTextFile( "foo.file" )
  .then( function ( t ) {
    document.write( t );
  } );