本文详解如何在 Autodesk Platform Services(APS,原 Forge)中正确创建存储桶(Bucket),涵盖身份认证、请求参数规范、常见 400 错误排查及前后端协同要点,助你稳定完成模型上传前的基础设施配置。 在 Autodesk Platform Services(APS
本文详解如何在 Autodesk Platform Services(APS,原 Forge)中正确创建存储桶(Bucket),涵盖身份认证、请求参数规范、常见 400 错误排查及前后端协同要点,助你稳定完成模型上传前的基础设施配置。
在 Autodesk Platform Services(APS)的生态里,存储桶(Bucket)扮演着核心存储单元的角色,设计模型、纹理、SVF 资源等对象都存放在这里。需要明确的是,它并非 Forge Viewer 的内置功能,而是由对象存储服务(OSS)API提供的底层服务。Viewer 只负责加载那些已经成功上传并完成格式转换的模型资源。因此,准确的说法不是“在 Forge Viewer 中创建 Bucket”,真正的流程应该是:通过 OSS API 创建 Bucket → 上传文件 → 调用 Model Derivative API 进行格式转换 → 最终由 Forge Viewer 加载 SVF/SVF2 衍生文件。
下面,我们将梳理实现的关键步骤和常见的排查要点。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
Bucket Key 的格式要求非常严格,必须满足以下条件:
在代码中使用 config.credentials.client_id.toLowerCase() + '-' + req.body.bucketKey 来拼接是个好习惯,但务必确保 req.body.bucketKey 本身已经过清洗。前端可以这样处理:$('#newBucketKey').val().trim().replace(/[^a-z0-9_-]/g, '')。
const { BucketsApi, PostBucketsPayload } = require('forge-apis');
// 推荐做法:显式构造 payload 并进行校验
router.post('/buckets', async (req, res, next) => {
const bucketKey = (req.body.bucketKey || '').trim();
if (!bucketKey) {
return res.status(400).json({ error: 'bucketKey is required and cannot be empty' });
}
const payload = new PostBucketsPayload();
payload.bucketKey = `${config.credentials.client_id.toLowerCase()}-${bucketKey}`; // 例如 'myapp-prod-models'
payload.policyKey = 'persistent'; // 注意:值必须是 'persistent'(全小写),而不是 'Persistent'
try {
const bucketsApi = new BucketsApi();
const result = await bucketsApi.createBucket(
payload,
{}, // opts(可选参数)
req.oauth_client, // 2-legged client 实例
req.oauth_token // 有效的、包含 bucket:create 权限的 2-legged token
);
res.status(201).json(result); // 正确返回 201 Created 及 bucket 信息
} catch (err) {
console.error('Failed to create bucket:', err.response.body || err.message);
next(err);
}
});
注意事项:
policyKey只接受 'transient' 或 'persistent'(必须全小写),文档里有时会误写成 'Transient'/'Persistent',这是引发 400 错误的典型原因;- 使用
res.status(201)更符合 RESTful API 的规范(资源创建成功);- 建议捕获
err.response.body来输出详细错误信息(例如{ "reason": "Invalid bucket key format" }),便于精准定位问题。
function createNewBucket() {
const bucketKey = $('#newBucketKey').val().trim().replace(/[^a-z0-9_-]/g, '');
if (!bucketKey) {
alert('请输入有效的 bucketKey(仅含小写字母、数字、-、_)');
return;
}
$.ajax({
url: '/api/forge/oss/buckets',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ bucketKey }), // 直接传递字符串,无需额外包装
headers: {
'Authorization': 'Bearer ' + getAccessToken() // 确保 token 已刷新且有效
},
success: function (res) {
$('#userHubs').jstree(true).refresh();
$('#createBucketModal').modal('hide');
alert('Bucket 创建成功:' + res.bucketKey);
},
error: function (xhr) {
const msg = xhr.responseJSON.reason || xhr.statusText;
alert(`创建失败:${xhr.status} ${msg}`);
console.error('Bucket creation error:', xhr);
}
});
}
| 检查项 | 是否合规 | 说明 |
|---|---|---|
| 回调地址(Callback URL)一致性 | □ | APS 应用设置页 vs 代码中 OAuth redirect_uri 必须完全一致 |
| 令牌权限范围(Token scope) | □ | 必含 bucket:create,推荐 data:write bucket:create |
| Bucket Key 格式 | □ | 全小写、3–128 字符、仅含 [a-z0-9_-] |
| 策略键(policyKey)值 | □ | 仅支持 'transient' 或 'persistent'(全小写) |
| 请求头与请求体 | □ | Content-Type: application/json,请求体为 {"bucketKey":"xxx"} |
完成上述配置后,Bucket 的创建过程就能稳定运行了。之后,便可以无缝衔接文件上传(使用 BucketsApi.uploadObject)与模型翻译(调用 ModelDerivativeApi.translate),最终交由 Forge Viewer 进行渲染——这才是 APS 全链路工作的标准流程。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述