用JavaScript打开本地文件

时间:2016-08-04 01:09:10

标签: javascript ajax

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

有一个类似的问题here。它似乎与AJAX的异步功能有关。我现在几乎无法理解这些术语。我只是不明白为什么在这篇文章中XMLHttpRequest.open()的第三个参数设置为true

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

<!DOCTYPE html>
<html>
    <script>
        function readTextFile(file)
        {   
            var allText;
            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; // this is the part that goes wrong I think
        }

        t = readTextFile("foo.file");
        document.write(t) // print out "undeifned" instead of the correct answer

    </script>
</html>

1 个答案:

答案 0 :(得分:3)

这实际上很可能是范围问题。因为您正在异步设置allText,所以在函数返回后它不会立即可用。此外,您正在重新初始化函数中的allText,无论如何都会与返回的范围混淆。

函数返回后执行

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

移动document.write

<!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>

<强> Promisified:

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。

虽然正如Santiago Hernández指出的那样,XHR请求是同步的,并且范围问题与我最初假设的不同。问题在于在函数内重新声明变量,导致返回的变量未定义。