快速开始

前置准备

  1. 注册冰梭账号并登录 开放平台应用管理
  2. 创建应用,获取 AppKeyAppSecret
  3. 选择传输能力:
    • P2P 直传:点对点传输,文件不经过服务器,2G 内免费
    • 安全中转:文件经云端中转存储,支持离线传输和多次下载,消耗会员流量配额
两种模式独立使用:P2P 直传和安全中转是两种独立的传输模式,开发者根据场景选择使用。SDK 不会自动降级,两种模式需分别调用对应接口。

安装 SDK

冰梭开放平台提供 iceshuttle-js JavaScript SDK,适用于浏览器环境,内部封装了签名认证、WebRTC 信令、分块上传/下载等全部复杂逻辑。

JS
iceshuttle-js

浏览器端 SDK,支持 P2P 直传和安全中转两种传输模式

在线体验

引入方式

JavaScript
// 方式一:本地引入(下载 SDK 文件后放置到项目中)
import { IceShuttle, downloadBlob } from './sdk/iceshuttle.esm.js';

// 方式二:官网下载引入(适合无构建工具的项目)
// 下载地址:https://www.wringcloud.com/sdk/iceshuttle-js/dist/iceshuttle.min.js
<script src="./sdk/iceshuttle.min.js"></script>
<script>
  const { IceShuttle, downloadBlob } = window.IceShuttle;
</script>
文件格式说明:
  • iceshuttle.min.js — 压缩版,体积最小,适合生产环境(script 标签引入)
  • iceshuttle.esm.js — ES Module 格式,可读性好,适合开发调试(import 引入)
  • iceshuttle.umd.js — UMD 格式,兼容 script 标签和 import 两种引入方式

初始化客户端

使用 AppKeyAppSecret 初始化 SDK 客户端,SDK 会自动处理签名认证。

JavaScript
import { IceShuttle } from 'iceshuttle-js';

const client = new IceShuttle({
  appKey: 'your-app-key',         // 必填:应用 Key
  appSecret: 'your-app-secret',   // 必填:应用 Secret
  serverDomain: 'https://www.wringcloud.com',  // 可选:服务器地址
  debug: false                       // 可选:是否开启调试日志
});

初始化参数

参数类型必填说明
appKeystring必填应用 Key,在开放平台应用管理中获取
appSecretstring必填应用 Secret,在开放平台应用管理中获取
serverDomainstring可选服务器地址,默认 https://www.wringcloud.com
debugboolean可选是否开启调试日志,默认 false

P2P 直传

P2P 直传:基于 WebRTC 的点对点传输,文件不经过服务器中转,2G 内免费。发送方需保持页面打开,接收方通过链接直接接收,与冰梭首页体验一致。

传输流程

1
创建发送任务
调用 createP2PSender
2
获取接收链接
分享给接收方
3
发送文件
调用 sendFile
4
接收方接收
通过链接接收文件

发送文件

JavaScript
// 1. 创建 P2P 发送任务
const sender = await client.createP2PSender({
  fileName: file.name,             // 必填:文件名
  fileSize: file.size,             // 必填:文件大小(字节)
  password: '可选密码',            // 可选:传输密码
  maxReceiveCount: 1              // 可选:最大接收次数
});

// 2. 获取接收链接,分享给接收方
const receiveLink = sender.getReceiveLink();
console.log('接收链接:', receiveLink);

// 3. 发送文件(SDK 自动等待接收方连接并传输)
await sender.sendFile(file, {
  onProgress: (percent) => {
    console.log(`传输进度: ${percent.toFixed(1)}%`);
  },
  onComplete: (info) => {
    console.log('传输完成', info);
  },
  onError: (err) => {
    console.error('传输失败:', err);
  },
  onProcessing: (info) => {
    console.log(info.message); // 如 "正在校验文件..."
  }
});

// 4. 取消传输(可选)
await sender.cancel();

createP2PSender 参数

参数类型必填说明
fileNamestring必填文件名
fileSizenumber必填文件大小(字节)
passwordstring可选传输密码
maxReceiveCountnumber可选最大接收次数

sendFile 回调

回调参数说明
onProgresspercent: number传输进度百分比(0-100)
onCompleteinfo: {fileName, fileSize}传输完成
onErrorerr: string传输错误
onProcessinginfo: {message}处理中状态(如校验文件)

P2PSender 方法

方法返回值说明
getReceiveLink()string获取接收链接,分享给接收方
sendFile(file, callbacks)Promise发送文件,自动等待接收方连接
cancel()Promise取消传输

接收文件

接收方通过链接中的 transferIdtoken 接收文件。

JavaScript
// 从接收链接中解析 transferId 和 token
const receiver = await client.createP2PReceiver(transferId, token);

// 获取文件信息
console.log('文件名:', receiver.getFileName());

// 接收文件
await receiver.receiveFile({
  onProgress: (percent) => {
    console.log(`接收进度: ${percent.toFixed(1)}%`);
  },
  onComplete: ({ blob, fileName, fileSize }) => {
    // 触发浏览器下载
    downloadBlob(blob, fileName);
  },
  onError: (err) => {
    console.error('接收失败:', err);
  }
});

createP2PReceiver 参数

参数类型必填说明
transferIdstring必填传输 ID,从接收链接中获取
tokenstring必填接收令牌,从接收链接中获取

P2PReceiver 方法

方法返回值说明
getFileName()string获取文件名
receiveFile(callbacks)Promise接收文件,onComplete 参数为 {blob, fileName, fileSize}

安全中转

安全中转:文件经冰梭云端中转存储,支持离线传输和多次下载,消耗会员流量配额。发送方上传完成后即可关闭页面,接收方可随时下载。

传输流程

1
创建中转任务
调用 createRelaySender
2
获取下载链接
分享给接收方
3
上传文件
调用 sendFile
4
接收方下载
通过链接下载文件

发送文件

JavaScript
// 1. 创建安全中转任务
const sender = await client.createRelaySender({
  fileName: file.name,             // 必填:文件名
  fileSize: file.size,             // 必填:文件大小(字节)
  password: '可选密码',            // 可选:传输密码
  maxReceiveCount: 5,             // 可选:最大下载次数
  expireHours: 168               // 可选:链接有效期(小时)
});

// 2. 获取下载链接,分享给接收方
const downloadLink = sender.getDownloadLink();
console.log('下载链接:', downloadLink);

// 3. 上传文件(SDK 自动处理分块上传)
await sender.sendFile(file, {
  onProgress: (percent) => {
    console.log(`上传进度: ${percent.toFixed(1)}%`);
  },
  onComplete: (info) => {
    console.log('上传完成,等待接收方下载');
  },
  onError: (err) => {
    console.error('上传失败:', err);
  }
});

// 4. 取消传输(可选)
await sender.cancel();

createRelaySender 参数

参数类型必填说明
fileNamestring必填文件名
fileSizenumber必填文件大小(字节)
passwordstring可选传输密码
maxReceiveCountnumber可选最大下载次数
expireHoursnumber可选链接有效期(小时)

RelaySender 方法

方法返回值说明
getDownloadLink()string获取下载链接,分享给接收方
sendFile(file, callbacks)Promise上传文件,SDK 自动处理分块
cancel()Promise取消传输

接收文件

接收方通过链接中的 transferIdtoken 下载文件。

JavaScript
// 从下载链接中解析 transferId 和 token
const receiver = await client.createRelayReceiver(transferId, token);

// 获取文件信息
console.log('文件名:', receiver.getFileName());

// 下载文件为 Blob
const blob = await receiver.receiveFileAsBlob({
  onProgress: (percent) => {
    console.log(`下载进度: ${percent.toFixed(1)}%`);
  }
});

// 触发浏览器下载
downloadBlob(blob, receiver.getFileName());

createRelayReceiver 参数

参数类型必填说明
transferIdstring必填传输 ID,从下载链接中获取
tokenstring必填下载令牌,从下载链接中获取

RelayReceiver 方法

方法返回值说明
getFileName()string获取文件名
receiveFileAsBlob(callbacks)Promise<Blob>下载文件为 Blob

通用接口

查询任务状态

JavaScript
// 查询 P2P 传输状态
const p2pStatus = await client.getP2PTransferStatus(transferId);

// 查询安全中转传输状态
const relayStatus = await client.getRelayTransferStatus(transferId);

取消传输

JavaScript
// 取消 P2P 传输
await client.cancelP2PTransfer(transferId);

// 取消安全中转传输
await client.cancelRelayTransfer(transferId);

// 或直接调用 sender.cancel()
await sender.cancel();

下载工具

SDK 提供 downloadBlob 工具函数,用于触发浏览器文件下载。

JavaScript
import { downloadBlob } from 'iceshuttle-js';

// 触发浏览器下载
downloadBlob(blob, '文件名.txt');

错误码

错误码说明
200成功
400参数错误
401签名无效或时间戳过期
403权益不足或非会员
404传输任务不存在
410传输已过期或接收次数用尽
413文件大小超限
429频率限制或流量超限
500服务器错误

常见问题

P2P 和安全中转如何选择?

  • P2P 直传:发送方和接收方同时在线,文件 2G 以内,追求速度和免费
  • 安全中转:接收方可能离线,需要多次下载,文件较大,有会员权益

AppSecret 丢失怎么办?

应用管理 页面,点击「重置Secret」获取新的 AppSecret。原 Secret 立即失效。

SDK 是否支持自动降级?

SDK 不支持自动降级。P2P 直传和安全中转是两种独立的传输模式,需分别调用 createP2PSendercreateRelaySender。开发者可根据业务场景自行实现降级逻辑。

调用频率限制?

默认每个应用 100次/分钟。如需更高配额,请联系平台。

如何从接收链接中获取 transferId 和 token?

JavaScript
// P2P 接收链接格式:https://www.wringcloud.com/p2p/{transferId}?token={token}
// 安全中转下载链接格式:https://www.wringcloud.com/r/{transferId}?token={token}

function parseLink(link) {
  const url = new URL(link);
  const transferId = url.pathname.split('/').pop();
  const token = url.searchParams.get('token');
  return { transferId, token };
}

在线 Demo

我们提供了完整的 Demo 页面,包含 P2P 直传、安全中转、文件接收的全部交互逻辑,开发者可基于此 Demo 定制自己的界面。

Demo
在线演示

完整交互界面,可直接体验 P2P 直传和安全中转

打开 Demo
下载
Demo 源码

下载 Demo 页面源码,本地运行或集成到项目中

本地运行 Demo:
  1. 下载 demo/index.htmldist/iceshuttle.esm.js
  2. 保持相对路径关系(demo 目录与 dist 目录同级)
  3. 用浏览器直接打开 index.html 即可运行

完整示例代码

JavaScript
import { IceShuttle, downloadBlob } from 'iceshuttle-js';

// 初始化
const client = new IceShuttle({
  appKey: 'your-app-key',
  appSecret: 'your-app-secret'
});

// ===== P2P 直传 =====
async function p2pSend(file) {
  const sender = await client.createP2PSender({
    fileName: file.name,
    fileSize: file.size
  });
  console.log('接收链接:', sender.getReceiveLink());
  await sender.sendFile(file, {
    onProgress: (p) => console.log(p + '%'),
    onComplete: () => console.log('完成')
  });
}

async function p2pReceive(transferId, token) {
  const receiver = await client.createP2PReceiver(transferId, token);
  await receiver.receiveFile({
    onProgress: (p) => console.log(p + '%'),
    onComplete: ({ blob, fileName }) => downloadBlob(blob, fileName)
  });
}

// ===== 安全中转 =====
async function relaySend(file) {
  const sender = await client.createRelaySender({
    fileName: file.name,
    fileSize: file.size
  });
  console.log('下载链接:', sender.getDownloadLink());
  await sender.sendFile(file, {
    onProgress: (p) => console.log(p + '%'),
    onComplete: () => console.log('上传完成')
  });
}

async function relayReceive(transferId, token) {
  const receiver = await client.createRelayReceiver(transferId, token);
  const blob = await receiver.receiveFileAsBlob({
    onProgress: (p) => console.log(p + '%')
  });
  downloadBlob(blob, receiver.getFileName());
}