在开发应用时,我们经常需要实现数据同步功能。例如我之前开发的表单填写工具(QuickFillForm),如果不保存到网盘,换个浏览器数据就丢失了;但如果接入 OneDrive 同步,用户就能在各个设备上无缝使用。本文将以这个实际案例为例,详细说明如何申请和配置 OneDrive API,帮助开发者快速实现网盘同步功能。
应用场景
OneDrive API 适用于以下开发场景:
- 跨设备数据同步: 浏览器插件、桌面应用的配置和数据同步
- 文件备份与恢复: 自动备份用户数据到云端,支持一键恢复
- 协作与分享: 实现文件共享、多人协作编辑功能
- 离线访问: 支持离线读取数据,在线自动同步
前置准备
在开始之前,你需要准备:
- ✅ Microsoft 账号(个人账号或工作/学校账号均可)
- ✅ 开发环境(本文以浏览器插件为例)
- ✅ 基础的 JavaScript/API 调用知识
💡 提示: OneDrive API 提供了免费的开发者配额,个人应用完全够用。
第一步: 注册 Azure 应用
1.1 访问 Azure Portal
- 打开浏览器,访问 Azure Portal
- 使用你的 Microsoft 账号登录
- 个人账号(如 Outlook、Hotmail 邮箱)
- 工作或学校账号(如公司/学校提供的 Office 365 账号)
- 如果没有 Azure 账号,可以免费注册
📌 注意: 即使没有 Azure 订阅,也可以注册应用。免费账号足够用于开发测试。
1.2 进入应用注册页面
- 在 Azure Portal 首页的搜索栏中输入 “Azure Active Directory” 或 “Microsoft Entra ID”
- 点击搜索结果中的 Azure Active Directory 服务
- 在左侧菜单中找到 “应用注册” (App registrations)
- 点击顶部的 "+ 新注册" (New registration) 按钮
1.3 填写应用基本信息
在应用注册页面,需要填写以下关键信息:
应用名称
- 字段: 名称 (Name)
- 示例:
QuickFillForm Extension或我的数据同步应用 - 说明: 这是应用的显示名称,用户授权时会看到此名称
支持的账户类型
选择应用的用户范围,推荐选择:
- ✅ 任何组织目录(任何 Azure AD 目录 - 多租户)中的帐户和个人 Microsoft 帐户(例如,Skype、Xbox)
- 英文选项: Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)
为什么选择这个选项?
- 支持个人 Microsoft 账号(最广泛的用户群)
- 支持企业和学校账号
- 不限制组织,任何人都可以使用你的应用
其他选项说明:
- 仅此组织目录: 仅限你的组织内部使用
- 任何组织目录: 仅限企业/学校账号,不支持个人账号
- 仅个人 Microsoft 账户: 仅支持个人账号
重定向 URI (Redirect URI)
这是 OAuth 认证完成后的回调地址,不同应用类型配置不同:
浏览器插件 (Chrome/Edge):
- 平台类型: Web
- URI 格式:
https://<YOUR_EXTENSION_ID>.chromiumapp.org/onedrive - 临时示例:
https://abcdefghijklmnopqrstuvwxyz123456.chromiumapp.org/onedrive
Web 应用:
- 平台类型: Web
- URI 格式:
https://yourdomain.com/callback - 本地开发:
http://localhost:3000/callback
桌面应用:
- 平台类型: 公共客户端/本机
- URI 格式:
https://login.microsoftonline.com/common/oauth2/nativeclient
⚠️ 重要: 浏览器插件的 Extension ID 需要在插件安装后才能获取,稍后我们会更新这个配置。可以先填写一个临时值,或者留空后面再添加。
1.4 完成注册
确认信息无误后,点击页面底部的 “注册” (Register) 按钮。
注册成功后,会自动跳转到应用的 概述 (Overview) 页面,这里显示了应用的基本信息和重要 ID。
第二步: 配置 API 权限
注册完应用后,需要为应用添加访问 OneDrive 的权限。
2.1 进入 API 权限页面
- 在应用详情页面的左侧菜单中,点击 “API 权限” (API permissions)
- 你会看到默认已经添加了
User.Read权限(这是用于读取用户基本信息的权限)
2.2 添加 Microsoft Graph 权限
- 点击页面中的 "+ 添加权限" (Add a permission) 按钮
- 在右侧弹出的面板中,点击 “Microsoft Graph”
- 选择 “委托的权限” (Delegated permissions)
💡 权限类型说明:
- 委托的权限 (Delegated permissions): 应用代表已登录用户访问数据,需要用户授权
- 应用程序权限 (Application permissions): 应用以自己的身份访问数据,无需用户登录,需要管理员同意
2.3 选择所需权限
在搜索框中搜索并勾选以下权限:
Files.ReadWrite.AppFolder (推荐)
- 权限名称:
Files.ReadWrite.AppFolder - 权限级别: 委托的权限
- 作用: 允许应用读写应用专用文件夹中的文件
- 优势: 最安全的权限,应用只能访问自己创建的
Apps/<AppName>文件夹 - 适用场景: 大多数应用数据同步场景
示例存储路径:
OneDrive/
└── Apps/
└── QuickFillForm/
├── quickfillform-data.json
└── backup/
offline_access (必需)
- 权限名称:
offline_access - 权限级别: 委托的权限
- 作用: 允许应用在用户离线时访问数据
- 用途: 获取刷新令牌(refresh token),在访问令牌过期后自动续期
Files.ReadWrite.All (可选,不推荐)
- 权限名称:
Files.ReadWrite.All - 权限级别: 委托的权限
- 作用: 允许应用读写用户的所有文件
- 风险: 权限范围过大,可能引起用户担忧
- 适用场景: 需要访问用户整个 OneDrive 的应用(如文件管理器)
2.4 确认添加权限
- 勾选好权限后,点击底部的 “添加权限” (Add permissions) 按钮
- 返回 API 权限页面,确认列表中显示以下权限:
- ✅
User.Read(默认) - ✅
Files.ReadWrite.AppFolder - ✅
offline_access
- ✅
2.5 授予管理员同意 (可选)
- 如果你是组织管理员,可以点击 “为 [组织名称] 授予管理员同意” 按钮
- 对于个人账号或公共应用,此步骤可以跳过
- 用户首次使用时会看到授权页面,点击"接受"即可
第三步: 获取应用凭据
3.1 复制 Client ID (应用程序 ID)
- 在应用详情页面的 “概述” (Overview) 选项卡中
- 找到 “应用程序(客户端) ID” (Application (client) ID)
- 这是一个 GUID 格式的字符串,类似:
12345678-1234-1234-1234-123456789abc - 点击旁边的复制图标,将 Client ID 保存到安全的地方
🔒 安全提示: Client ID 是公开信息,可以在前端代码中使用。但不要将它与 Client Secret 混淆。
3.2 是否需要 Client Secret?
对于不同类型的应用,Client Secret 的需求不同:
| 应用类型 | 是否需要 Client Secret | 原因 |
|---|---|---|
| 浏览器插件 | ❌ 不需要 | 使用隐式授权流程或 PKCE |
| 单页应用 (SPA) | ❌ 不需要 | 前端代码无法安全存储密钥 |
| Web 应用 (有后端) | ✅ 需要 | 在服务器端安全存储 |
| 桌面/移动应用 | ❌ 不需要 | 使用 PKCE 授权流程 |
如果需要 Client Secret,创建方法如下:
- 在左侧菜单中点击 “证书和密码” (Certificates & secrets)
- 点击 "+ 新客户端密码" (New client secret)
- 输入描述(如 “生产环境密钥”),选择过期时间
- 点击 “添加” (Add)
- 立即复制密钥值,此密钥只显示一次
⚠️ 警告: Client Secret 是敏感信息,必须妥善保管,不能提交到代码仓库。
3.3 配置身份验证设置
- 在左侧菜单点击 “身份验证” (Authentication)
- 确认 重定向 URI 已正确添加
- 向下滚动到 “隐式授权和混合流” (Implicit grant and hybrid flows) 部分
对于浏览器插件或 SPA,需要启用:
- ✅ 勾选 “访问令牌” (Access tokens)
- ✅ 勾选 “ID 令牌” (ID tokens)
对于使用授权码流程的应用,可以不勾选上述选项
- 点击页面底部的 “保存” (Save) 按钮
第四步: 配置应用代码
以浏览器插件为例,说明如何在代码中配置 OneDrive API。
4.1 获取浏览器插件的 Extension ID
如果你正在开发浏览器插件:
- 打开 Chrome 或 Edge 浏览器
- 访问
chrome://extensions/(Chrome) 或edge://extensions/(Edge) - 开启右上角的 “开发者模式” (Developer mode)
- 点击 “加载已解压的扩展程序” (Load unpacked)
- 选择你的插件项目文件夹
- 安装成功后,在插件卡片上找到 “ID” 字段,复制扩展 ID
- 类似:
abcdefghijklmnopqrstuvwxyz123456
- 类似:
4.2 更新 Azure 重定向 URI
- 返回 Azure Portal 的应用注册页面
- 进入 “身份验证” (Authentication)
- 更新或添加重定向 URI:
https://abcdefghijklmnopqrstuvwxyz123456.chromiumapp.org/onedrive- 将
abcdefghijklmnopqrstuvwxyz123456替换为实际的扩展 ID
- 将
- 点击 “保存” (Save)
4.3 在代码中配置 Client ID
以 QuickFillForm 插件为例,在 onedrive-sync.js 文件中配置:
class OneDriveSync {
constructor() {
// 替换为你的 Azure 应用程序 ID (Client ID)
this.clientId = '12345678-1234-1234-1234-123456789abc';
// 获取当前插件的 ID
this.redirectUri = `https://${chrome.runtime.id}.chromiumapp.org/onedrive`;
// Microsoft Graph API 端点
this.graphEndpoint = 'https://graph.microsoft.com/v1.0';
// 应用专用文件夹路径
this.appFolderPath = '/me/drive/special/approot';
// 请求的权限范围
this.scopes = [
'Files.ReadWrite.AppFolder',
'offline_access'
];
}
// 获取访问令牌
async getAccessToken() {
return new Promise((resolve, reject) => {
chrome.identity.launchWebAuthFlow({
url: this.getAuthUrl(),
interactive: true
}, (redirectUrl) => {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError);
return;
}
// 从回调 URL 中提取 access_token
const url = new URL(redirectUrl);
const token = url.hash.match(/access_token=([^&]*)/)?.[1];
if (token) {
resolve(token);
} else {
reject(new Error('无法获取访问令牌'));
}
});
});
}
// 构建授权 URL
getAuthUrl() {
const params = new URLSearchParams({
client_id: this.clientId,
response_type: 'token',
redirect_uri: this.redirectUri,
scope: this.scopes.join(' '),
response_mode: 'fragment'
});
return `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?${params}`;
}
// 上传文件到 OneDrive
async uploadFile(fileName, content) {
const token = await this.getAccessToken();
const response = await fetch(
`${this.graphEndpoint}${this.appFolderPath}:/${fileName}:/content`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(content)
}
);
if (!response.ok) {
throw new Error(`上传失败: ${response.statusText}`);
}
return await response.json();
}
// 从 OneDrive 下载文件
async downloadFile(fileName) {
const token = await this.getAccessToken();
const response = await fetch(
`${this.graphEndpoint}${this.appFolderPath}:/${fileName}:/content`,
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
if (!response.ok) {
throw new Error(`下载失败: ${response.statusText}`);
}
return await response.json();
}
}
// 使用示例
const onedriveSync = new OneDriveSync();
// 上传数据
onedriveSync.uploadFile('data.json', { key: 'value' })
.then(() => console.log('上传成功'))
.catch(err => console.error('上传失败:', err));
// 下载数据
onedriveSync.downloadFile('data.json')
.then(data => console.log('下载的数据:', data))
.catch(err => console.error('下载失败:', err));
4.4 Web 应用配置示例
对于传统 Web 应用(有后端),使用授权码流程更安全:
// 前端代码
function loginWithOneDrive() {
const clientId = 'YOUR_CLIENT_ID';
const redirectUri = 'https://yourdomain.com/callback';
const scopes = 'Files.ReadWrite.AppFolder offline_access';
const authUrl = `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?` +
`client_id=${clientId}` +
`&response_type=code` +
`&redirect_uri=${encodeURIComponent(redirectUri)}` +
`&scope=${encodeURIComponent(scopes)}`;
window.location.href = authUrl;
}
// 后端代码 (Node.js Express 示例)
app.get('/callback', async (req, res) => {
const code = req.query.code;
// 用授权码换取访问令牌
const tokenResponse = await fetch('https://login.microsoftonline.com/common/oauth2/v2.0/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
code: code,
redirect_uri: 'https://yourdomain.com/callback',
grant_type: 'authorization_code'
})
});
const tokenData = await tokenResponse.json();
// 保存 access_token 和 refresh_token
req.session.accessToken = tokenData.access_token;
req.session.refreshToken = tokenData.refresh_token;
res.redirect('/dashboard');
});
4.5 配置 manifest.json (浏览器插件)
在插件的 manifest.json 中添加必要的权限:
{
"manifest_version": 3,
"name": "QuickFillForm",
"version": "1.0.0",
"permissions": [
"identity",
"storage"
],
"host_permissions": [
"https://login.microsoftonline.com/*",
"https://graph.microsoft.com/*"
],
"oauth2": {
"client_id": "12345678-1234-1234-1234-123456789abc.chromiumapp.org",
"scopes": [
"Files.ReadWrite.AppFolder",
"offline_access"
]
}
}
第五步: 测试同步功能
5.1 测试用户认证
- 在应用中触发 OneDrive 登录流程
- 浏览器会打开 Microsoft 登录页面
- 输入 Microsoft 账号和密码登录
- 首次使用会看到权限请求页面:
- 显示应用名称
- 列出请求的权限
- 显示应用发布者信息
- 点击 “接受” (Accept) 按钮授权
5.2 测试文件上传
浏览器插件示例:
// 测试上传功能
async function testUpload() {
const testData = {
name: '张三',
email: 'zhangsan@example.com',
phone: '13800138000'
};
try {
const result = await onedriveSync.uploadFile('test-data.json', testData);
console.log('✅ 上传成功:', result);
} catch (error) {
console.error('❌ 上传失败:', error);
}
}
testUpload();
5.3 测试文件下载
// 测试下载功能
async function testDownload() {
try {
const data = await onedriveSync.downloadFile('test-data.json');
console.log('✅ 下载成功:', data);
} catch (error) {
console.error('❌ 下载失败:', error);
}
}
testDownload();
5.4 验证文件存储位置
- 登录 OneDrive 网页版
- 在左侧菜单中找到 “应用” (Apps) 文件夹
- 进入你的应用文件夹,例如
Apps/QuickFillForm/ - 确认文件已成功上传
5.5 测试跨设备同步
- 在设备 A 上传数据
- 在设备 B 上登录同一 Microsoft 账号
- 下载数据,验证是否与设备 A 一致
- 修改数据后再次上传
- 在设备 A 上下载,验证是否更新
常见问题与解决方案
Q1: 无法获取访问令牌
错误信息:
AADSTS50011: The redirect URI specified in the request does not match
原因分析:
- Client ID 配置错误
- 重定向 URI 不匹配
- Extension ID 更改后未更新 Azure 配置
解决方案:
检查代码中的
clientId是否正确复制// 错误: 多余的空格或特殊字符 this.clientId = '12345678-1234-1234-1234-123456789abc '; // 正确 this.clientId = '12345678-1234-1234-1234-123456789abc';确认 Azure 应用注册中的重定向 URI 与代码完全一致
- Azure 配置:
https://abcdefg123456.chromiumapp.org/onedrive - 代码配置:
https://abcdefg123456.chromiumapp.org/onedrive - 注意区分大小写和尾部斜杠
- Azure 配置:
保存配置后等待 2-5 分钟让配置生效
Q2: 权限被拒绝,无法读写文件
错误信息:
403 Forbidden: Access denied
原因分析:
- 权限未正确添加
- 用户未授权
- 使用了错误的 API 端点
解决方案:
- 在 Azure Portal 检查是否已添加
Files.ReadWrite.AppFolder权限 - 清除用户授权,重新登录并同意权限
// 清除缓存的令牌 chrome.identity.clearAllCachedAuthTokens(() => { console.log('已清除缓存,请重新登录'); }); - 确认使用正确的 API 路径:
// 正确: 使用应用专用文件夹 const path = '/me/drive/special/approot:/data.json:/content'; // 错误: 使用根目录 (需要 Files.ReadWrite.All 权限) const path = '/me/drive/root:/data.json:/content';
Q3: 访问令牌过期
错误信息:
401 Unauthorized: The access token has expired
原因分析:
- Access Token 默认有效期 1 小时
- 未实现 Refresh Token 自动刷新机制
解决方案:
实现令牌刷新逻辑:
class OneDriveSync {
constructor() {
this.accessToken = null;
this.refreshToken = null;
this.tokenExpiry = null;
}
// 获取有效的访问令牌
async getValidAccessToken() {
// 如果令牌未过期,直接返回
if (this.accessToken && this.tokenExpiry > Date.now()) {
return this.accessToken;
}
// 如果有刷新令牌,尝试刷新
if (this.refreshToken) {
return await this.refreshAccessToken();
}
// 否则重新登录
return await this.getAccessToken();
}
// 刷新访问令牌
async refreshAccessToken() {
const response = await fetch('https://login.microsoftonline.com/common/oauth2/v2.0/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
client_id: this.clientId,
refresh_token: this.refreshToken,
grant_type: 'refresh_token'
})
});
const data = await response.json();
this.accessToken = data.access_token;
this.refreshToken = data.refresh_token;
this.tokenExpiry = Date.now() + (data.expires_in * 1000);
// 保存到本地存储
chrome.storage.local.set({
onedrive_access_token: this.accessToken,
onedrive_refresh_token: this.refreshToken,
onedrive_token_expiry: this.tokenExpiry
});
return this.accessToken;
}
}
Q4: 找不到扩展 ID
解决方案:
- 访问浏览器的扩展管理页面:
- Chrome:
chrome://extensions/ - Edge:
edge://extensions/
- Chrome:
- 确保已开启"开发者模式"
- Extension ID 显示在扩展卡片上,格式类似:
ID: abcdefghijklmnopqrstuvwxyz123456 - 如果是已发布的扩展,可以在 Chrome Web Store 的 URL 中找到:
https://chrome.google.com/webstore/detail/extension-name/abcdefghijklmnopqrstuvwxyz123456
Q5: 文件上传成功但在 OneDrive 中找不到
原因分析:
- 使用了应用专用文件夹,路径在
Apps/<AppName>/下 - OneDrive 网页版界面可能有延迟
- 文件名或路径错误
解决方案:
- 在 OneDrive 网页版中,导航到:
OneDrive → 应用 (Apps) → QuickFillForm - 等待 1-2 分钟,刷新页面
- 使用 API 查询文件是否存在:
// 列出应用文件夹中的所有文件 async function listFiles() { const token = await onedriveSync.getValidAccessToken(); const response = await fetch( 'https://graph.microsoft.com/v1.0/me/drive/special/approot/children', { headers: { 'Authorization': `Bearer ${token}` } } ); const data = await response.json(); console.log('文件列表:', data.value); }
Q6: 跨域请求被阻止 (CORS)
错误信息:
Access to fetch at 'https://graph.microsoft.com/...' has been blocked by CORS policy
原因分析:
- 在普通网页中直接请求 Graph API
- 未在
manifest.json中配置host_permissions
解决方案:
方案一: 使用后端代理 (推荐)
// 前端调用后端 API
fetch('/api/onedrive/upload', {
method: 'POST',
body: JSON.stringify(data)
});
// 后端转发到 Microsoft Graph
app.post('/api/onedrive/upload', async (req, res) => {
const response = await fetch('https://graph.microsoft.com/v1.0/...', {
headers: { 'Authorization': `Bearer ${accessToken}` }
});
// ...
});
方案二: 浏览器插件配置
{
"host_permissions": [
"https://login.microsoftonline.com/*",
"https://graph.microsoft.com/*"
]
}
Q7: 授权页面显示"需要管理员审批"
错误信息:
AADSTS65001: The user or administrator has not consented to use the application
原因分析:
- 组织策略要求管理员批准应用
- 请求的权限需要管理员同意
解决方案:
- 如果你是管理员,在 Azure Portal 中授予管理员同意
- 如果不是管理员,联系 IT 部门批准应用
- 使用个人 Microsoft 账号测试(个人账号无需管理员同意)
- 减少权限请求,只使用委托权限而不是应用权限
安全最佳实践
1. 保护 Client Secret
// ❌ 错误: 在前端代码中硬编码密钥
const clientSecret = 'your-secret-key-123456';
// ✅ 正确: 在后端使用环境变量
const clientSecret = process.env.AZURE_CLIENT_SECRET;
2. 使用最小权限原则
// ❌ 错误: 请求过多权限
const scopes = [
'Files.ReadWrite.All',
'Mail.Read',
'Contacts.ReadWrite'
];
// ✅ 正确: 只请求必需的权限
const scopes = [
'Files.ReadWrite.AppFolder',
'offline_access'
];
3. 安全存储令牌
// ✅ 浏览器插件: 使用 chrome.storage.local
chrome.storage.local.set({
onedrive_token: encryptedToken // 最好加密存储
});
// ✅ Web 应用: 使用 HttpOnly Cookie
res.cookie('access_token', token, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
4. 定期检查应用活动
- 登录 Azure Portal
- 进入应用注册 → 你的应用
- 查看 “概述” 中的使用情况统计
- 检查异常登录和 API 调用
5. 处理敏感数据
// 上传前加密敏感数据
async function uploadSecureData(data) {
const encrypted = await encryptData(data);
await onedriveSync.uploadFile('secure-data.enc', encrypted);
}
// 下载后解密
async function downloadSecureData() {
const encrypted = await onedriveSync.downloadFile('secure-data.enc');
return await decryptData(encrypted);
}
进阶技巧
1. 实现文件版本管理
OneDrive 自动保留文件版本历史,可以通过 API 访问:
async function getFileVersions(fileName) {
const token = await onedriveSync.getValidAccessToken();
const response = await fetch(
`https://graph.microsoft.com/v1.0/me/drive/special/approot:/${fileName}:/versions`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
const data = await response.json();
return data.value; // 返回版本列表
}
2. 实现增量同步
通过 Delta API 获取文件变化:
async function syncChanges(deltaLink) {
const token = await onedriveSync.getValidAccessToken();
const url = deltaLink ||
'https://graph.microsoft.com/v1.0/me/drive/special/approot/delta';
const response = await fetch(url, {
headers: { 'Authorization': `Bearer ${token}` }
});
const data = await response.json();
// 处理变化的文件
for (const item of data.value) {
if (item.deleted) {
console.log('文件已删除:', item.name);
} else {
console.log('文件已更新:', item.name);
}
}
// 保存 deltaLink 供下次使用
return data['@odata.deltaLink'];
}
3. 实现冲突解决
async function smartSync(fileName, localData) {
try {
// 下载远程文件
const remoteData = await onedriveSync.downloadFile(fileName);
// 比较时间戳
if (remoteData.lastModified > localData.lastModified) {
// 远程更新,下载覆盖本地
return { action: 'download', data: remoteData };
} else if (localData.lastModified > remoteData.lastModified) {
// 本地更新,上传覆盖远程
await onedriveSync.uploadFile(fileName, localData);
return { action: 'upload', data: localData };
} else {
// 智能合并
const merged = mergeData(localData, remoteData);
await onedriveSync.uploadFile(fileName, merged);
return { action: 'merge', data: merged };
}
} catch (error) {
// 文件不存在,直接上传
if (error.status === 404) {
await onedriveSync.uploadFile(fileName, localData);
return { action: 'create', data: localData };
}
throw error;
}
}
4. 批量操作
使用批处理 API 提高性能:
async function batchUpload(files) {
const token = await onedriveSync.getValidAccessToken();
const requests = files.map((file, index) => ({
id: index.toString(),
method: 'PUT',
url: `/me/drive/special/approot:/${file.name}:/content`,
headers: {
'Content-Type': 'application/json'
},
body: file.content
}));
const response = await fetch('https://graph.microsoft.com/v1.0/$batch', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ requests })
});
return await response.json();
}
相关资源
官方文档
开发工具
- 🛠️ Graph Explorer - 在线测试 API
- 🛠️ Microsoft Graph SDK - 各语言 SDK
- 🛠️ Postman Collection - API 调试
