【Deno】文件服务脚本

147 阅读1分钟

描述

快速启动一个服务浏览本地文件列表及内容, 当前deno版本1.34.0

代码

// fileServer.ts
/**
 * 文件服务
 */
const port = 8000;
// 监听网络连接
const serverListener = Deno.listen({ port: port })
console.log(`File server running on http://localhost:${port}/`);

// 处理网络连接
for await (const server of serverListener) {
  handleHttp(server).catch((e) => console.error(e));
}

/** 处理HTTP
 * @example
 * ```ts
 * // Example usage 1
 * handleHttp(server)
 * // Example usage 2
 * await handleHttp(server)
 * // Example usage 3
 * handleHttp(server).catch((e) => console.error(e));
 * ```
 * @param {Deno.Conn} conn HTTP连接对象
 * @returns {Promise<void>}
 */
async function handleHttp(conn: Deno.Conn) {
  const httpConn = Deno.serveHttp(conn)
  for await (const requestEvent of httpConn) {
    const url = new URL(requestEvent.request.url);
    const filepath = decodeURIComponent(url.pathname);
    // 获取文件后缀
    const filePathArray = filepath.split('.');
    // 如果访问的是目录,不是文件,遍历目录下所有文件列表并转为html返回
    if (filePathArray.length < 2) {
      // 异步迭代器, 访问/根目录,无需拼接"/"
      const filePathTmp = `${filePathArray[0].length > 1 ? filePathArray[0] + '/' : '/' }`
      const fileList = await Deno.readDir('.'+filePathTmp);
      const fileNames = [];
      for await (const file of fileList) {
        fileNames.push(`<a href="${filePathTmp+file.name}">${filePathTmp+file.name}</a><br />`);
      }
      await requestEvent.respondWith(new Response(fileNames.join('\n'), { status: 200, headers: {
        'content-type': 'text/html'
      } }));
      continue 
    }
    // 访问的是文件,直接读取文件内容并返回
    let fileContent;
    try {
      const decoder = new TextDecoder("utf-8");
      fileContent = decoder.decode(await Deno.readFile('.' + filepath));
    } catch (error) {
      console.error(error);
      await requestEvent.respondWith(new Response('该资源不存在', { status: 404 }));
      continue
    }
    // 正常返回
    await requestEvent.respondWith(new Response(fileContent, { status: 200 }));
  }
}

运行

deno run --allow-net --allow-read fileServer.ts

安装到全局

deno install -AF fileServer.ts

效果

image.png