Deno 中如何实现跨域文件下载?

前言

在前端开发中,我们经常需要下载其他域名下的文件,但是由于浏览器的同源策略,我们在 JavaScript 中不能直接通过 AJAX 或 Fetch API 下载非同源 URL 的文件。在这种情况下,我们可以使用 CORS(跨域资源共享)或 JSONP(JSON with Padding)等方式来跨域下载文件。但是,这些方法有一些局限性,例如,CORS 需要服务端支持,JSONP 只能下载 JSON 格式的文件等。

在最近的 Deno 发布中,它提供了一种新的方法来下载跨域文件。本文将介绍如何在 Deno 中实现跨域文件下载。

实现跨域文件下载的一般思路

在 Deno 中下载跨域文件的一般思路如下:

  1. 通过 HTTP 请求获取跨域文件的二进制数据
  2. 将二进制数据写入到本地文件中

这听起来很简单,但是在实践中有许多细节需要注意。我们需要处理 HTTP 请求级别的细节,例如请求头,身份验证、超时和错误处理等。我们还需要考虑如何正确地处理二进制数据,确保没有出现损坏或丢失的情况。在下面的示例代码中,我们将逐步演示如何将这些细节整合在一起完成跨域文件下载的任务。

示例代码

我们使用 Deno 标准库中的 fetch() 方法来发起 HTTP 请求,并使用传入的文件名和文件路径将文件写入本地。这里是基本的实现代码:

import { writeFile } from "https://deno.land/std/fs/mod.ts";

async function downloadFile(url: string, fileName: string) {
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`Failed to fetch ${url}. Status code: ${response.status}`);
  }

  const blob = await response.blob();

  await writeFile(fileName, new Uint8Array(await blob.arrayBuffer()));
}

这里我们使用了异步函数,等待 Deno 实例中的 fetch() 方法返回一个 response 对象。我们检查响应对象的状态码是否为 200,如果状态码不是 200,我们抛出一个错误。否则,我们获取响应的二进制数据并将其写入本地文件中。

最后,我们可以在主函数中调用 downloadFile() 方法来下载指定文件:

const url = "https://domain.com/file.txt";
const fileName = "./file.txt";

await downloadFile(url, fileName);

高级应用

在一些需要身份验证的情况下,我们需要将身份验证令牌添加到 HTTP 请求标头中。例如,当我们需要下载需要身份验证的文件时,我们需要将令牌添加到请求头中。我们可以使用 Deno 中默认的 fetch() 方法来设置头文件。

const HEADERS = new Headers({
  "Authorization": "Bearer " + token
});

const response = await fetch(url, {
  headers: HEADERS
});

在超时的情况下,我们需要指定一个最大超时时间,并在请求超时后手动取消请求以避免浪费资源。

const responsePromise = fetch(url);

const timeoutPromise = new Promise<Response>((_, reject) => {
  setTimeout(() => reject('Request timed out.'), MAX_TIMEOUT);
});

const response = await Promise.race([responsePromise, timeoutPromise]);

if (response === undefined) {
  throw new Error('Request timed out.');
}

另外,我们可以在写入文件之前使用 Deno.open() 方法打开文件并获取文件的资源 ID。一旦我们打开了文件,我们就可以使用更底层的函数,例如 await Deno.writeAll() 来写入数据。

const file = await Deno.open(fileName, { write: true, createNew: true });
const bytesWritten = await Deno.writeAll(file, new Uint8Array(await blob.arrayBuffer()));
await Deno.close(file.rid);

总结

在本文中,我们讨论了如何在 Deno 中实现跨域文件下载,并演示了下载文件的示例代码。我们介绍了一些高级应用程序,例如在请求中设置标头,处理超时和控制写入文件的更底层的方法。我们希望本文对 Deno 的初学者和中级开发者来说具有指导意义,以便他们可以在实际开发中更轻松地实现跨域文件下载。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a4d9d5add4f0e0ffd334f9


纠错反馈