楔子
在研究 Go中文网(https://studygolang.com) studygolang的源码时,从它的配置文件中发现了可以免费使用的对象存储服务,可以上传和下载图片,刚好给我自己的开源IM项目提供了补充,值得一用。
; 图片存储在七牛云,如果没有可以通过 https://portal.qiniu.com/signup?code=3lfz4at7pxfma 免费申请
[qiniu]
access_key = xxxxxx
secret_key = xxxxxxx
bucket_name = xxxx
up_host = xxx
; CND HTTP 的域名
http_domain = xxx
; CND HTTPS 的域名
https_domain = xxx
接下来
果断的去申请开发者账号,从申请到审核通过,总共不到10分钟,不得不感叹它的效率之高。
正文开始
没有写代码,所以先通过postman来测试一下。
创建存储空间
输入空间名字,权限里面选择公开(通过一个URL都能访问?),点击下一步即可。
表单上传
首先,找到上传URL:
存储区域 | 地域简称 | 上传域名 |
---|---|---|
华东 | z0 | 服务器端上传:http://up.qiniup.com |
客户端上传: http://upload.qiniup.com | ||
华北 | z1 | 服务器端上传:http://up-z1.qiniup.com |
客户端上传:http://upload-z1.qiniup.com | ||
华南 | z2 | 服务器端上传:http://up-z2.qiniup.com |
客户端上传:http://upload-z2.qiniup.com | ||
北美 | na0 | 服务器端上传:http://up-na0.qiniup.com |
客户端上传:http://upload-na0.qiniup.com | ||
东南亚 | as0 | 服务器端上传:http://up-as0.qiniup.com |
客户端上传:http://upload-as0.qiniup.com |
因为我选的华东地区,所以我的url是 http://upload.qiniup.com,先用postman试一下。
查阅官方文档:https://developer.qiniu.com/kodo/manual/1272/form-upload
<form method="post" action="http://upload.qiniup.com/"
enctype="multipart/form-data">
<input name="key" type="hidden" value="<resource_key>">
<input name="x:<custom_name>" type="hidden" value="<custom_value>">
<input name="token" type="hidden" value="<upload_token>">
<input name="crc32" type="hidden" />
<input name="accept" type="hidden" />
<input name="file" type="file" />
<input type="submit" value="上传文件" />
</form>
只需要upload_token和file即可。
获取upload_token
在安全机制这块好像控制的挺严格的,还需要通过代码生成一个上传口令。
参考:https://github.com/qiniu/api.v7/blob/master/examples/create_uptoken.go
Go代码生成(没成功)
附官方例子(通过生成的token,上传文件报bad token的错误):
package main
import (
"encoding/base64"
"fmt"
"os"
"strings"
//"github.com/qiniu/api.v7/v7/auth"
//"github.com/qiniu/api.v7/v7/storage"
// 上面的报错,替换成下面的。执行:go get -u github.com/qiniu/api.v7 安装
"github.com/qiniu/api.v7/auth"
"github.com/qiniu/api.v7/storage"
)
var (
accessKey = os.Getenv("QINIU_ACCESS_KEY") // 在 https://portal.qiniu.com/user/key可以找到
secretKey = os.Getenv("QINIU_SECRET_KEY")
bucket = os.Getenv("QINIU_TEST_BUCKET") // 替换成自己的空间名字
)
func main() {
// 简单上传凭证
putPolicy := storage.PutPolicy{
Scope: bucket,
}
mac := auth.New(accessKey, secretKey)
upToken := putPolicy.UploadToken(mac)
fmt.Println(upToken)
// 设置上传凭证有效期
putPolicy = storage.PutPolicy{
Scope: bucket,
}
putPolicy.Expires = 7200 //示例2小时有效期
upToken = putPolicy.UploadToken(mac)
fmt.Println(upToken)
// 覆盖上传凭证
// 需要覆盖的文件名
keyToOverwrite := "qiniu.mp4"
putPolicy = storage.PutPolicy{
Scope: fmt.Sprintf("%s:%s", bucket, keyToOverwrite),
}
upToken = putPolicy.UploadToken(mac)
fmt.Println(upToken)
// 自定义上传回复凭证
putPolicy = storage.PutPolicy{
Scope: bucket,
ReturnBody: `{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}`,
}
upToken = putPolicy.UploadToken(mac)
fmt.Println(upToken)
// 带回调业务服务器的凭证(JSON方式)
putPolicy = storage.PutPolicy{
Scope: bucket,
CallbackURL: "http://api.example.com/qiniu/upload/callback",
CallbackBody: `{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}`,
CallbackBodyType: "application/json",
}
upToken = putPolicy.UploadToken(mac)
fmt.Println(upToken)
// 带回调业务服务器的凭证(URL方式)
putPolicy = storage.PutPolicy{
Scope: bucket,
CallbackURL: "http://api.example.com/qiniu/upload/callback",
CallbackBody: "key=$(key)&hash=$(etag)&bucket=$(bucket)&fsize=$(fsize)&name=$(x:name)",
}
upToken = putPolicy.UploadToken(mac)
fmt.Println(upToken)
// 带数据处理的凭证
saveMp4Entry := base64.URLEncoding.EncodeToString([]byte(bucket + ":avthumb_test_target.mp4"))
saveJpgEntry := base64.URLEncoding.EncodeToString([]byte(bucket + ":vframe_test_target.jpg"))
//数据处理指令,支持多个指令
avthumbMp4Fop := "avthumb/mp4|saveas/" + saveMp4Entry
vframeJpgFop := "vframe/jpg/offset/1|saveas/" + saveJpgEntry
//连接多个操作指令
persistentOps := strings.Join([]string{
avthumbMp4Fop, vframeJpgFop}, ";")
pipeline := "test"
putPolicy = storage.PutPolicy{
Scope: bucket,
PersistentOps: persistentOps,
PersistentPipeline: pipeline,
PersistentNotifyURL: "http://api.example.com/qiniu/pfop/notify",
}
upToken = putPolicy.UploadToken(mac)
fmt.Println(upToken)
}
执行前需安装依赖
go get -u -v github.com/qiniu/api.v7
在线生成
http://jsfiddle.net/gh/get/extjs/4.2/icattlecoder/jsfiddle/tree/master/uptoken
通过官方的连接,打开后,替换AK/SK(在这里查看https://portal.qiniu.com/user/key)和Bucket后,点击左上角的 Run 得到token,放入到postman之后上传成功,没有报Bad token错误了。
使用postman测试上传
通过运行上面的代码,得到upload_token之后,我们可以使用postman来测试。
多了一个文件。
URL格式:http:// [域名] / 返回的key,如:
http://q7zje1vvy.bkt.clouddn.com/Fv9V3DRs36_v4clMzCOo-QuSVA_B
浏览器打开:
参考
七牛云上传下载操作指南:https://developer.qiniu.com/kodo/kb/1336/upload-download-instructions