图片上传oss--先拿server端签名再上传oss,返回id值

Posted 逍遥超儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图片上传oss--先拿server端签名再上传oss,返回id值相关的知识,希望对你有一定的参考价值。

目前项目oss阿里云存储图片,图片上传主要步骤是:前端从服务端拿到签名signature,再上传到oss上busket里,上传成功返回图片id (imgId),最后再给server端;

注:官网上有个例子,也有封装的插件一个,可参考使用,[服务端签名直传并设置上传回调](https://help.aliyun.com/document_detail/31927.html?spm=5176.doc31923.2.2.RseG9d);但因技术有限,未使用;

项目使用angularjs开发的,常用方法$http请求上传都会报跨域问题,加入使用cors解决跨域但报405 不支持该方法
在使用postman测试接口,可以实现提交无误,问题出在哪呢?   后发现postman提交是以form-data格式,对,它使用form表单提交的;



之后写了个简单demo,可以实现,后采用一下该方法form表单提交上传图片,(后发现某宝亦使用该方法,这都是后话了)

再存在问题,就是使用form表单提交后会跳转页面问题,相信很多伙伴都遇到,也有自己的解决方案,

常用方法为 跳转空的iframe 和 jquery-form.js插件 的方法, 某宝用后者,这里我们用后者;

注意事项:
- 使用form表单提交 该form再该页面外部不能有form进行包裹,否则无效
- 使用 jquery-form.js方法 必须再页面再加载一次,才有效果,否则报错 ajaxSubmit is not undefind

 目前解决方案,代码优化如下:

 1 <form id="fromName" enctype="multipart/form-data"
 2                           action="http://******-shanghai.aliyuncs.com"
 3                           onsubmit="return saveFormImg();"
 4                           method="post" style="padding-bottom: 100px;">
 5 
 6     <input type="hidden" name="key" ng-value="key"/>
 7     <input type="hidden" name="policy" ng-value="policy"/>
 8     <input type="hidden" name="OSSAccessKeyId" ng-value="ossid"/>
 9     <input type="hidden" name="signature" ng-value="sign"/>
10     <input type="hidden" name="callback" ng-value="call"/>
11     <input type="hidden" name="x:openid" ng-value="od"/>
12     <input type="file" name="file"/>
13     <input type="submit" value="上 传"/>
14 
15 </form>
16     <script type="text/javascript" src="http://malsup.github.io/jquery.form.js"></script>
17     <script>
18         function saveFormImg() {
19 
20             $("#fromName").ajaxSubmit(function (message) {
21     //      console.log(message);
22                 if (message.code == \'200\') {
23                     var detailImgID = message.data.imgId;
24  
25                     if (window.localStorage) {
26                         localStorage.setItem("OssDetailImgId2", detailImgID);
27                     } else {
28                         Cookie.write("OssDetailImgId2", detailImgID);
29                     }
30                  } else {
31                      alert(\'图片有误,请重新选择并提交\');
32                  }
33 
34          });
35               return false;   //阻止跳转
36 
37         }
38     </script>

 

  注释: action 为你oss的url;input上ng-value为angularjs的数据绑定一种方法;

x:openid 是项目认证的id,您可能用不到;


form表单配置  *
   id  | enctype   |action  | method  |onsubmit
   ----|---------- |--------|---------|---------
   id名| 提交格式    | 地址   |   方式   | 事件

 *加上action 和input,上传oss共需要8个参数,数据通过第一次请求服务端拿签名得到,通过数据绑定到form表单input上提交*

返回的id需要传给server端,因页面作用域的原因,controller层拿不到每次页面form提交返回的id;这里使用页面传参通过localStotage写入读出,考虑到浏览器有可能不支持H5 localStorage,可存Cookie中
使用方法: 先按照你的借口需求,写一个简单的form提交,包含必要的key-value值, 然后在输入框中填入数据,测试,成功的话,便可修改,简化,数据绑定,等等;


最初的demo:
<form id="fromName" enctype="multipart/form-data" 
action="http://******-shanghai.aliyuncs.com"
onsubmit="return saveFormImg();" method="post">

<label for= "keyName">keyName</label> <input id="keyName" type="text">


/* ... 多个input,具体看你的接口...*/
    <input type="file" name="file"/>
<input type="submit" value="上 传"/>
 </form>
 <script type="text/javascript" src="http://malsup.github.io/jquery.form.js"></script>
 <script>
 function saveFormImg() {
     $("#fromName").ajaxSubmit(function (message) {
         console.log(message);
             
     });
     return false;   //阻止跳转

  }
</script>


 

目前初步实现了功能开发,有什么不足之处,望大家指点,共同进步,目前时间,能力有限,后期尝试打算做成指令,或者封装成插件使用;

如您有更好的办法,还望不吝赐教!



以上是关于图片上传oss--先拿server端签名再上传oss,返回id值的主要内容,如果未能解决你的问题,请参考以下文章

Web直传阿里云OSS服务端临签名总结 2021-01-28

四步解决!OSS对象存储文件上传功能(服务端签名后直传,建议收藏)

使用金山云的phpSDK报错了,吗T.T

商城项目09_品牌管理菜单快速显示开关阿里云进行文件上传结合Alibaba管理OSS服务端签名后直传

商城项目09_品牌管理菜单快速显示开关阿里云进行文件上传结合Alibaba管理OSS服务端签名后直传

前端图片直传OSS试验