开发者社区> 问答> 正文

OSS如何实现表单上传?


适用场景


指的是用户使用OSS API中的Post Object请求来完成Object的上传,上传的Object不能超过5GB。非常适合嵌入在HTML网页中来上传Object,比较常见的应用场景是网站应用,以招聘网站为例子:

不使用表单上传表单上传
流程对比1. 网站用户上传简历 2. 网站服务器回应上传页面 3. 简历被上传到网站服务器 4. 网站服务器再将简历上传到OSS1. 网站用户上传简历 2. 网站服务器回应上传页面 3. 简历上传到OSS


上传限制

  • 大小限制:使用表单上传时,Object不能超过5GB。
  • 命名限制:使用UTF-8编码
  • 长度必须在1-1023字节之间
  • 不能以“/”或者“\”字符开头


使用表单上传的好处

  • 从流程上,少了一步转发。
  • 从架构上来说,原来的上传都统一走网站服务器,上传量过大时,瓶颈在网站服务器,可能需要扩容网站服务器。采用表单上传后,上传都是直接从客户端发送到OSS。上传量过大时,压力都在OSS上,由OSS来保障服务质量。


上传的安全及授权


  • 为防止第三方未经授权向开发者的Bucket上传Object,OSS提供了Bucket和Object级别的访问权限控制,详细解释见OSS细粒度的权限控制

  • 为了授权给第三方上传,这里使用的是Post Policy的机制,详细见 PostObject


使用表单上传的基本步骤


  1. 构建一个Post Policy。
    Post请求的Policy表单域用于验证请求的合法性。例如可以指定上传的大小,可以指定上传的Object名字等,上传成功后客户端跳转到的URL,上传成功后客户端收到的状态码。具体请参考Post Policy
    例如如下Policy,网站用户能上传的过期时间是2115-01-27T10:56:19Z(这里为了测试成功写的过期时间很长,实际使用中不建议这样设置),能上传的文件最大为104857600字节。[backcolor=transparent] [backcolor=transparent][backcolor=transparent]Python[backcolor=transparent]代码为例子,[backcolor=transparent]Policy[backcolor=transparent][backcolor=transparent]json[backcolor=transparent]格式的字符串。
  2. [backcolor=transparent] policy[backcolor=transparent]=[backcolor=transparent]"{\"expiration\":\"2115-01-27T10:56:19Z\",\"conditions\":[[\"content-length-range\", 0, 104857600]]}"
将Policy字符串进行base64编码。用OSS的AccessKeySecret对base64编码后的Policy进行签名。构建上传的HTML页面。打开HTML页面,选择文件上传。
完整Python代码示例:
  1. [backcolor=transparent]#coding=utf8
  2. [backcolor=transparent]import[backcolor=transparent] md5
  3. [backcolor=transparent]import[backcolor=transparent] hashlib
  4. [backcolor=transparent]import[backcolor=transparent] base64
  5. [backcolor=transparent]import[backcolor=transparent] hmac
  6. [backcolor=transparent]from[backcolor=transparent] optparse [backcolor=transparent]import[backcolor=transparent] [backcolor=transparent]OptionParser
  7. [backcolor=transparent]def[backcolor=transparent] convert_base64[backcolor=transparent]([backcolor=transparent]input[backcolor=transparent]):
  8. [backcolor=transparent]    [backcolor=transparent]return[backcolor=transparent] base64[backcolor=transparent].[backcolor=transparent]b64encode[backcolor=transparent]([backcolor=transparent]input[backcolor=transparent])
  9. [backcolor=transparent]def[backcolor=transparent] get_sign_policy[backcolor=transparent]([backcolor=transparent]key[backcolor=transparent],[backcolor=transparent] policy[backcolor=transparent]):
  10. [backcolor=transparent]    [backcolor=transparent]return[backcolor=transparent] base64[backcolor=transparent].[backcolor=transparent]b64encode[backcolor=transparent]([backcolor=transparent]hmac[backcolor=transparent].[backcolor=transparent]new[backcolor=transparent]([backcolor=transparent]key[backcolor=transparent],[backcolor=transparent] policy[backcolor=transparent],[backcolor=transparent] hashlib[backcolor=transparent].[backcolor=transparent]sha1[backcolor=transparent]).[backcolor=transparent]digest[backcolor=transparent]())
  11. [backcolor=transparent]def[backcolor=transparent] get_form[backcolor=transparent]([backcolor=transparent]bucket[backcolor=transparent],[backcolor=transparent] endpoint[backcolor=transparent],[backcolor=transparent] access_key_id[backcolor=transparent],[backcolor=transparent] access_key_secret[backcolor=transparent],[backcolor=transparent] out[backcolor=transparent]):
  12. [backcolor=transparent]    [backcolor=transparent]#1 构建一个Post Policy
  13. [backcolor=transparent]    policy[backcolor=transparent]=[backcolor=transparent]"{\"expiration\":\"2115-01-27T10:56:19Z\",\"conditions\":[[\"content-length-range\", 0, 1048576]]}"
  14. [backcolor=transparent]    [backcolor=transparent]print[backcolor=transparent]([backcolor=transparent]"policy: %s"[backcolor=transparent] [backcolor=transparent]%[backcolor=transparent] policy[backcolor=transparent])
  15. [backcolor=transparent]    [backcolor=transparent]#2 将Policy字符串进行base64编码
  16. [backcolor=transparent]    base64policy [backcolor=transparent]=[backcolor=transparent] convert_base64[backcolor=transparent]([backcolor=transparent]policy[backcolor=transparent])
  17. [backcolor=transparent]    [backcolor=transparent]print[backcolor=transparent]([backcolor=transparent]"base64_encode_policy: %s"[backcolor=transparent] [backcolor=transparent]%[backcolor=transparent] base64policy[backcolor=transparent])
  18. [backcolor=transparent]    [backcolor=transparent]#3 用OSS的AccessKeySecret对编码后的Policy进行签名
  19. [backcolor=transparent]    signature [backcolor=transparent]=[backcolor=transparent] get_sign_policy[backcolor=transparent]([backcolor=transparent]access_key_secret[backcolor=transparent],[backcolor=transparent] base64policy[backcolor=transparent])
  20. [backcolor=transparent]    [backcolor=transparent]#4 构建上传的HTML页面
  21. [backcolor=transparent]    form [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]'''
  22. [backcolor=transparent]    <html>
  23. [backcolor=transparent]        <meta http-equiv=content-type content="text/html; charset=UTF-8">
  24. [backcolor=transparent]        <head><title>OSS表单上传(PostObject)</title></head>
  25. [backcolor=transparent]        <body>
  26. [backcolor=transparent]            <form  action="http://%s.%s" method="post" enctype="multipart/form-data">
  27. [backcolor=transparent]                <input type="text" name="OSSAccessKeyId" value="%s">
  28. [backcolor=transparent]                <input type="text" name="policy" value="%s">
  29. [backcolor=transparent]                <input type="text" name="Signature" value="%s">
  30. [backcolor=transparent]                <input type="text" name="key" value="upload/${filename}">
  31. [backcolor=transparent]                <input type="text" name="success_action_redirect" value="http://oss.aliyun.com">
  32. [backcolor=transparent]                <input type="text" name="success_action_status" value="201">
  33. [backcolor=transparent]                <input name="file" type="file" id="file">
  34. [backcolor=transparent]                <input name="submit" value="Upload" type="submit">
  35. [backcolor=transparent]            </form>
  36. [backcolor=transparent]        </body>
  37. [backcolor=transparent]    </html>
  38. [backcolor=transparent]    '''[backcolor=transparent] [backcolor=transparent]%[backcolor=transparent] [backcolor=transparent]([backcolor=transparent]bucket[backcolor=transparent],[backcolor=transparent] endpoint[backcolor=transparent],[backcolor=transparent] access_key_id[backcolor=transparent],[backcolor=transparent] base64policy[backcolor=transparent],[backcolor=transparent] signature[backcolor=transparent])
  39. [backcolor=transparent]    f [backcolor=transparent]=[backcolor=transparent] open[backcolor=transparent]([backcolor=transparent]out[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"wb"[backcolor=transparent])
  40. [backcolor=transparent]    f[backcolor=transparent].[backcolor=transparent]write[backcolor=transparent]([backcolor=transparent]form[backcolor=transparent])
  41. [backcolor=transparent]    f[backcolor=transparent].[backcolor=transparent]close[backcolor=transparent]()
  42. [backcolor=transparent]    [backcolor=transparent]print[backcolor=transparent]([backcolor=transparent]"form is saved into %s"[backcolor=transparent] [backcolor=transparent]%[backcolor=transparent] out[backcolor=transparent])
  43. [backcolor=transparent]if[backcolor=transparent] __name__ [backcolor=transparent]==[backcolor=transparent] [backcolor=transparent]'__main__'[backcolor=transparent]:
  44. [backcolor=transparent]    parser [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]OptionParser[backcolor=transparent]()
  45. [backcolor=transparent]    parser[backcolor=transparent].[backcolor=transparent]add_option[backcolor=transparent]([backcolor=transparent]""[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"--bucket"[backcolor=transparent],[backcolor=transparent] dest[backcolor=transparent]=[backcolor=transparent]"bucket"[backcolor=transparent],[backcolor=transparent] help[backcolor=transparent]=[backcolor=transparent]"specify "[backcolor=transparent])
  46. [backcolor=transparent]    parser[backcolor=transparent].[backcolor=transparent]add_option[backcolor=transparent]([backcolor=transparent]""[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"--endpoint"[backcolor=transparent],[backcolor=transparent] dest[backcolor=transparent]=[backcolor=transparent]"endpoint"[backcolor=transparent],[backcolor=transparent] help[backcolor=transparent]=[backcolor=transparent]"specify"[backcolor=transparent])
  47. [backcolor=transparent]    parser[backcolor=transparent].[backcolor=transparent]add_option[backcolor=transparent]([backcolor=transparent]""[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"--id"[backcolor=transparent],[backcolor=transparent] dest[backcolor=transparent]=[backcolor=transparent]"id"[backcolor=transparent],[backcolor=transparent] help[backcolor=transparent]=[backcolor=transparent]"access_key_id"[backcolor=transparent])
  48. [backcolor=transparent]    parser[backcolor=transparent].[backcolor=transparent]add_option[backcolor=transparent]([backcolor=transparent]""[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"--key"[backcolor=transparent],[backcolor=transparent] dest[backcolor=transparent]=[backcolor=transparent]"key"[backcolor=transparent],[backcolor=transparent] help[backcolor=transparent]=[backcolor=transparent]"access_key_secret"[backcolor=transparent])
  49. [backcolor=transparent]    parser[backcolor=transparent].[backcolor=transparent]add_option[backcolor=transparent]([backcolor=transparent]""[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"--out"[backcolor=transparent],[backcolor=transparent] dest[backcolor=transparent]=[backcolor=transparent]"out"[backcolor=transparent],[backcolor=transparent] help[backcolor=transparent]=[backcolor=transparent]"out put form"[backcolor=transparent])
  50. [backcolor=transparent]    [backcolor=transparent]([backcolor=transparent]opts[backcolor=transparent],[backcolor=transparent] args[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]=[backcolor=transparent] parser[backcolor=transparent].[backcolor=transparent]parse_args[backcolor=transparent]()
  51. [backcolor=transparent]    [backcolor=transparent]if[backcolor=transparent] opts[backcolor=transparent].[backcolor=transparent]bucket [backcolor=transparent]and[backcolor=transparent] opts[backcolor=transparent].[backcolor=transparent]endpoint [backcolor=transparent]and[backcolor=transparent] opts[backcolor=transparent].[backcolor=transparent]id [backcolor=transparent]and[backcolor=transparent] opts[backcolor=transparent].[backcolor=transparent]key [backcolor=transparent]and[backcolor=transparent] opts[backcolor=transparent].[backcolor=transparent]out[backcolor=transparent]:
  52. [backcolor=transparent]        get_form[backcolor=transparent]([backcolor=transparent]opts[backcolor=transparent].[backcolor=transparent]bucket[backcolor=transparent],[backcolor=transparent] opts[backcolor=transparent].[backcolor=transparent]endpoint[backcolor=transparent],[backcolor=transparent] opts[backcolor=transparent].[backcolor=transparent]id[backcolor=transparent],[backcolor=transparent] opts[backcolor=transparent].[backcolor=transparent]key[backcolor=transparent],[backcolor=transparent] opts[backcolor=transparent].[backcolor=transparent]out[backcolor=transparent])
  53. [backcolor=transparent]    [backcolor=transparent]else[backcolor=transparent]:
  54. [backcolor=transparent]        [backcolor=transparent]print[backcolor=transparent] [backcolor=transparent]"python %s --bucket=your-bucket --endpoint=oss-cn-hangzhou.aliyuncs.com --id=your-access-key-id --key=your-access-key-secret --out=out-put-form-name"[backcolor=transparent] [backcolor=transparent]%[backcolor=transparent] __file__

将此段代码保存为post_object.py,然后用python post_object.py来运行。
  1. [backcolor=transparent]用法:
  2. [backcolor=transparent]python post_object[backcolor=transparent].[backcolor=transparent]py [backcolor=transparent]--[backcolor=transparent]bucket[backcolor=transparent]=您的[backcolor=transparent]Bucket[backcolor=transparent] [backcolor=transparent]--[backcolor=transparent]endpoint[backcolor=transparent]=[backcolor=transparent]Bucket[backcolor=transparent]对应的[backcolor=transparent]OSS[backcolor=transparent]域名[backcolor=transparent] [backcolor=transparent]--[backcolor=transparent]id[backcolor=transparent]=您的[backcolor=transparent]AccessKeyId[backcolor=transparent] [backcolor=transparent]--[backcolor=transparent]key[backcolor=transparent]=您的[backcolor=transparent]AccessKeySecret[backcolor=transparent] [backcolor=transparent]--[backcolor=transparent]out[backcolor=transparent]=输出的文件名
  3. [backcolor=transparent]示例:
  4. [backcolor=transparent]python post_object[backcolor=transparent].[backcolor=transparent]py [backcolor=transparent]--[backcolor=transparent]bucket[backcolor=transparent]=[backcolor=transparent]oss[backcolor=transparent]-[backcolor=transparent]sample [backcolor=transparent]--[backcolor=transparent]endpoint[backcolor=transparent]=[backcolor=transparent]oss[backcolor=transparent]-[backcolor=transparent]cn[backcolor=transparent]-[backcolor=transparent]hangzhou[backcolor=transparent].[backcolor=transparent]aliyuncs[backcolor=transparent].[backcolor=transparent]com [backcolor=transparent]--[backcolor=transparent]id[backcolor=transparent]=[backcolor=transparent]tphpxp [backcolor=transparent]--[backcolor=transparent]key[backcolor=transparent]=[backcolor=transparent]ZQNJzf4QJRkrH4[backcolor=transparent] [backcolor=transparent]--[backcolor=transparent]out[backcolor=transparent]=[backcolor=transparent]post[backcolor=transparent].[backcolor=transparent]html

[backcolor=transparent]注意:
  • 构建的表单中 success_action_redirect value=http://oss.aliyun.com 表示上传成功后跳转的页面。可以替换成您自己的页面。
  • 构建的表单中success_action_status value=201表示的是上传成功后返回的状态码为201。可以替换。
  • 假如指定生成的HTML文件为post.html,打开post.html,选择文件上传。在这个例子中如果成功则会跳转到OSS的主页面。


功能使用参考



最佳实践



相关参考链接

展开
收起
青衫无名 2017-10-17 15:28:29 1964 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
OSS运维进阶实战手册 立即下载
《OSS运维基础实战手册》 立即下载
OSS运维基础实战手册 立即下载