本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《
阿里云开发者社区用户服务协议
》和
《
阿里云开发者社区知识产权保护指引
》。如果您发现本社区中有涉嫌抄袭的内容,填写
侵权投诉表单
进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
前文《Nestjs+Vue实现阿里云OSS服务端签名直传》详细介绍了如何在 Nest 服务端基于 Post Policy 生成临时签名,响应给客户端,再由客户端实现文件直传 OSS 的过程。
这种方案的优点是能减轻应用服务器的压力,节省流量,最重要是安全。但是在客户端将文件上传到 OSS 的结果如何,文件存储的地址,文件大小等信息,客户端和服务端都全然不知。
所以在前面的基础上,可以再加上一个步骤,
设置上传回调
,这样 OSS 完成文件存储后,可以将相关信息响应给服务端,服务端将处理结果再响应给 OSS ,再由 OSS 将信息响应给客户端。整个流程如下:
需要准备一个域名和一台有公网IP的服务器,将域名解析到服务器上,在服务器中运行 Nest 程序,用来和 OSS 服务通信。
存储桶的跨域设置
前文中将允许的来源设置为了 *,现在改为真实的域名。
在存储桶中选择“数据安全” - “跨域设置”,编辑跨域规则:
Nest 服务端
使用前文示例的代码,只需要做一些小小的改动即可。
添加路由方法
在
oss.controller.ts
中新增一个控制器方法,用来处理 OSS 发来的回调请求。从请求头中解析出
x-oss-pub-key-url
,用来判断请求来源,并且从请求体中解析出文件信息。
import {
Controller, Get, Post } from '@nestjs/common';
import {
OssService } from './oss.service';
@Controller('oss')
export class OssController {
constructor(private oss: OssService) {
@Post('result')
getResult(@Headers('x-oss-pub-key-url') xOssPubKeyUrl: string, @Body() file: any) {
return this.oss.getResult(xOssPubKeyUrl, file);
添加服务方法
在 oss.service.ts
先修改原来的 getSignature
方法,生成签名等信息后,还要设置回调请求需要的参数:
async getSignature() {
const config = {
callbackUrl: 'http://kunwu.tech:3000/oss/result',
const callback = {
callbackUrl: config.callbackUrl,
callbackBody:
'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}',
callbackBodyType: 'application/x-www-form-urlencoded',
return {
callback: Buffer.from(JSON.stringify(callback)).toString('base64'),
还需要再增加一个方法,来处理 OSS 发来的请求。它接收控制器传递的两个参数,判断请求来源是 OSS 服务器之后,就可以将文件信息响应给客户端:
async getResult(xOssPubKeyUrl: string, file: any) {
const pubKeyAddr = Buffer.from(xOssPubKeyUrl, 'base64').toString('ascii');
if (!pubKeyAddr.startsWith('https://gosspublic.alicdn.com/')) {
return {
status: 'verify not ok',
return {
status: 'Ok',
file,
在前面的基础之上,现在向服务器请求签名信息返回的结果中会包含一条 callback
:
向 OSS 上传文件时,需要将 callback
也携带上:
const handleUpload = async () => {
const ossData = await getOssData()
formdata.append('callback', ossData.callback)
在浏览器中选择一个文件上传到 OSS,查看下响应信息:
可以看到,这个信息就是我们在服务端设置的 /oss/result
接口的返回的数据:
return {
status: 'Ok',
file,
代码已上传,点击这里查看。
本文在上篇文章的基础上,增加了设置回调请求的步骤,这样就形成了一个完整的闭环:
客户端上传文件前,先请求临时签名
服务端生成临时签名,并设置回调请求地址
客户端拿到签名、回调请求地址等信息后,将文件上传到 OSS
OSS 完成文件存储后,按照回调地址将结果发送给服务器
服务器处理完后,将结果响应给 OSS
最后 OSS 将结果响应给客户端
这一块内容在文档中有详细的介绍,可以参考:
服务端签名直传并设置上传回调概述
Callback