快来看,浏览器也能访问本地电脑文件啦!!!

49 阅读2分钟

@[toc]

需求

在浏览器中打开本地文件夹并获取指定文件夹下的内容 在早期的时候呢,这些API确实是没有的,也就是根本不允许 在浏览器中读取本地文件夹里的信息,但是后期出现的 File API,逐渐可以实现该功能,它是允许用户授权给这个网站,去读取到它的一些本地信息

分析

针对以上问题,我们做几个实现步骤:

1. 如何弹出文件夹选择框

比如说网页上有一个按钮,点击后需要弹出一个文件夹的选择框 在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <link rel="shortcut icon" type="image/x-icon" href="/tit_logo.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>111</title>
</head>

<body>
    <div id="app">
        <button>打开文件夹</button>
    </div>
    <script>
        const btn = document.querySelector('button');
        btn.onclick = function () {
            // window.open
            showDirectoryPicker()
        }
    </script>
</body>

</html>

2. 如何获取文件夹中的内容

在这里插入图片描述

  1. 使用 showDirectoryPicker() 方法进行读取,该方法返回的是一个句柄,打印结果如下,返回结果很简单,只有一个文件类型和文件夹的名

    const btn = document.querySelector('button');
    btn.onclick = async function () {
        const handle = await showDirectoryPicker()
        console.log(handle)
    }
    

    在这里插入图片描述

  2. 获取该文件夹下的内容

    const btn = document.querySelector('button');
    btn.onclick = async function () {
         const handle = await showDirectoryPicker()
         await processHandle(handle)// 文件的操作都是异步的因此这里用异步进行处理
     }
     async function processHandle (handle) {
         if (handle.kind === 'file') {
             return
         }
         // entries:异步迭代器
         const entries = await handle.entries()
         for await (const entrie of entries) {
             console.log(entrie);
    
         }
     }
    

    在这里插入图片描述

  3. 获取到文件夹下的所有内容,就需要写一个递归方法

    <script>
       const btn = document.querySelector('button');
       btn.onclick = async function () {
           const handle = await showDirectoryPicker()
           await processHandle(handle)// 文件的操作都是异步的因此这里用异步进行处理
           console.log(handle);
       }
       async function processHandle (handle) {
           if (handle.kind === 'file') {
               return
           }
           // entries:异步迭代器
           const entries = await handle.values()
           handle.children = []
           for await (const subHandle of entries) {
               handle.children.push(subHandle)
               await processHandle(subHandle)
           }
       }
    </script>
    

    在这里插入图片描述

3. 如何读取文件内容

既然可以拿到该类型为 File 的文件,那么接下来就是读取文件的内容了

const file = await fileHandle.getFile()
const reader = new FileReader()
reader.onload = e => {
    console.log(e.target.result);
}
reader.readAsText(file)

在这里插入图片描述

我们看到和文件中的内容没有区别

在这里插入图片描述

4. 总体代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <link rel="shortcut icon" type="image/x-icon" href="/tit_logo.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>111</title>
</head>

<body>
    <div id="app">
        <button>打开文件夹</button>
    </div>
    <script>
        const btn = document.querySelector('button');
        btn.onclick = async function () {
            const handle = await showDirectoryPicker()
            await processHandle(handle)// 文件的操作都是异步的因此这里用异步进行处理
            const fileHandle = handle.children[0]
            const file = await fileHandle.getFile()
            const reader = new FileReader()
            reader.onload = e => {
                console.log(e.target.result);
            }
            reader.readAsText(file)
        }
        async function processHandle (handle) {
            if (handle.kind === 'file') {
                return
            }
            // entries:异步迭代器
            const entries = await handle.values()
            handle.children = []
            for await (const subHandle of entries) {
                handle.children.push(subHandle)
                await processHandle(subHandle)

            }
        }
    </script>
</body>

</html>