使用JS將APP(包括安卓和IOS)上傳到七牛 (上傳APP因此不考慮數據處理)javascript
uptoken使用JAVA後臺獲得html
七牛上傳基於plupload下面不詳述如何使用參見前端
七牛上傳的簡單案例也不詳述,參見官網事例很清楚了。就是參數必定看仔細!java
清除緩存問題ios
IOS APP上傳icon和ipa自動生成plistajax
補充:限制選擇文件類型;打開多個選擇文件窗口算法
1.使用前端獲取:
本人是個前端,在後臺還沒給出獲取uptoken接口時,我先選擇了使用JS(uptoken_func參數)獲取進行測試,代碼以下:詳細參見json
// uptoken_func: function (file) { // 在須要獲取uptoken時,該方法會被調用 /** * 上傳憑證算法實現參考 * 請注意External Resources項中引用的第三方CryptoJS庫 */ var genUpToken = function(accessKey, secretKey, putPolicy) { //SETP 2 var put_policy = JSON.stringify(putPolicy); //SETP 3 var encoded = base64encode(utf16to8(put_policy)); //SETP 4 var hash = CryptoJS.HmacSHA1(encoded, secretKey); var encoded_signed = hash.toString(CryptoJS.enc.Base64); //SETP 5 var upload_token = accessKey + ":" + safe64(encoded_signed) + ":" + encoded; console && console.log("upload_token=", upload_token) return upload_token; // }
費了半天勁,又是引入CryptoJS,又是加入utf16to8等等方法,最後仍是失敗了,生成了一個uptoken我用來上傳文件上傳失敗,就問七牛工單,他說uptoken過期或者錯誤,這就無法搞了也不知道爲何錯,就在沒有頭緒的時候後臺接口好了,得,用後臺接口,結束!(有童鞋用JS獲取了uptoken的能夠來交流)
不過在錯誤中學習到了uptoken的第三個值(用「:」分割的aaaa:aaaa:aaaa)能夠經過base64解碼獲得上傳策略。segmentfault
2.使用後臺獲取(我選擇的是java)
導入gson-1.6.jar和qiniu-java-sdk-7.0.0.jar,如下是qiniu的方法!是用uptoken,傳入須要的參數既能夠得到,本人不作後臺開發就不詳述,就是必定注意參數不要傳錯了,咱們搞了很久AK,SK複製錯了,若是提示uptoken錯誤多檢查幾遍參數。到此完成了一個最簡單的上傳。圖片描述api
奇葩同樣的大坑啊,原本就是剛剛上手qiniu還沒搞懂的時候還在鬱悶昨天還好好的怎麼過了一晚就上傳失敗了,查詢資料,全不費功夫社區有人踩過了。看第二個評論,簡單說就是設置uptoken參數不能上傳大文件,必須設置uptoken_url才行,做者說的第一個方法我進不去,就沒有糾結。這個是qiniu的bug!
你直接看源碼就知道它在判斷須要分塊的時候,js-sdk內部設置up.setOption的調用getUptoken(),that.tokenInfo在只填寫token的時候,仍是undefined,因此就出問題了。
由於tokenInfo是在走getNewUpToken()設置的,而getNewUpToken是走填了url纔會執行的函數。
剛剛拿到需求,思索一番,
方案一:生成一個可用覆蓋文件的uptoken;
方案二:qiniuJSjdk經過配置參數能夠覆蓋文件。
查閱API,社區資料,發現方案一能夠行的通,只需後臺uptoken方法時傳入key參數便可覆蓋服務器上面的key文件。
我原覺得key也是後臺給設定的存儲文件名,(這個key並非服務器存儲的最終文件名)後來才發現不是,詳細看scope參數。
指定上傳的目標資源空間 Bucket 和資源鍵 Key(key的長度最大爲750字節)。有兩種格式:
●<bucket>,表示容許用戶上傳文件到指定的 bucket。在這種格式下文件只能新增,若已存在同名資源上傳則會失敗。
●<bucket>:<key>,表示只容許用戶上傳指定 key的文件。在這種格式下文件默認容許修改,若已存在同名資源則會被覆蓋。若是隻但願上傳指定 key 的文件,而且不容許修改,那麼能夠將下面的insertOnly 屬性值設爲 1。
因爲後臺須要key,因此前臺在uptoken_url時傳參,例如:'/appstore/app/qiniuUploadToken?params=a.png'。
前臺有三個參數和文件名有關:
// unique_names: true, // 默認false,key爲文件名。若開啓該選項,JS-SDK會爲每一個文件自動生成key(文件名) // save_key: true, // 默認false。若在服務端生成uptoken的上傳策略中指定了sava_key,則開啓,SDK在前端將不對key進行任何處理 'Key': function (up, file) { // 若想在前端對每一個文件的key進行個性化處理,能夠配置該函數 // 該配置必需要在unique_names: false,save_key: false時才生效 var key = file.name;//**錯誤** // do something with key here return key }
重點看第三個參數,當時沒有在乎就這樣寫的,因此認爲給後臺傳的key就是服務器存儲的文件名,其實否則,是我在JS key中設置了var key = file.name。應該須要前端定一個名字,而不是文件原名。
看官方文檔給出以下解決方法,生成管理token,清除緩存。
可是客服給出了更好的解決方案
1、URL 問號傳參刷新:
2、在七牛雲存儲上刷新: 一、登陸portal.qiniu.com 二、工具刷新 三、API 接口文檔刷新:
3、只使用fusion cdn加速,且沒有使用七牛存儲
我選擇了最簡單的第一種,URL 問號傳參。(拋出問題:ios app是ipa url問號傳參,仍是plisturl問號傳參,仍是都須要,待測試驗證,以後更新!)
例如,若是 http://7xt44n.com2.z0.glb.qin...
這個圖片資源沒有更新, 能夠在該 URL 後面加上參數的形式來讓 CDN
強制刷新:http://7xt44n.com2.z0.glb.qin...,CDN
拿到這個 URL 後會強制回七牛的存儲中取回最新的資源。原理: (用戶建立空間爲普通平臺,在這個平臺下 url 是完整緩存的。也就是說。若是你帶了? 1234 這樣的查詢參數在文件 url
後面,就變成了不一樣的 url,因此不會命中 cdn 的緩存。會去原站七牛拉資源,這時候拉取到的資源就變成了覆蓋更新後的資源了。)
原先的ios部署很是不方便,須要上傳icon和ipa獲得地址後修改plist,再上傳plist。因此就想能不能作到自動。
仍是喜歡先查閱資料看看網上有沒有方案,一無所得。
方案以下:(如下代碼感謝導師的支持)
使用Arttemplate獲得一個模板
使用blob獲得一個blob數據用於生成file對象
使用七牛的表單上傳,結合XMLHttpRequest,formData獲得一個表單數據
詳細代碼:
function plist(icon57Url, icon512Url, ipaUrl, key,plistUrl) { var data = { icon57Url: icon57Url, icon512Url: icon512Url, ipaUrl: ipaUrl, }; var html = template('test', data); var blob = new Blob([html], {type: "text/plain"}); //document.getElementById('content').innerHTML = html; var Qiniu_UploadUrl = "http://up.qiniu.com"; var Qiniu_upload = function (f, token) { var xhr = new XMLHttpRequest(); xhr.open('POST', Qiniu_UploadUrl, true); var formData, startDate; formData = new FormData(); //if (key !== null && key !== undefined) formData.append('key', key); formData.append('token', token); formData.append('name', key + '.plist'); formData.append('chunk', 0); formData.append('chunks', 1); formData.append('key', key + '.plist'); formData.append('file', f, key + '.plist'); var taking; xhr.upload.addEventListener("loadstart", function (up, file) { /*up.settings.multipart_params = { filename : "xucheng.docx" };*/ }, false); xhr.upload.addEventListener("progress", function (evt) { if (evt.lengthComputable) { /*var nowDate = new Date().getTime(); taking = nowDate - startDate; var x = (evt.loaded) / 1024; var y = taking / 1000; var uploadSpeed = (x / y); var formatSpeed; if (uploadSpeed > 1024) { formatSpeed = (uploadSpeed / 1024).toFixed(2) + "Mb\/s"; } else { formatSpeed = uploadSpeed.toFixed(2) + "Kb\/s"; }*/ //var percentComplete = Math.round(evt.loaded * 100 / evt.total); //progressbar.progressbar("value", percentComplete); // console && console.log(percentComplete, ",", formatSpeed); } }, false); xhr.onreadystatechange = function (response) { if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseText != "") { var blkRet = JSON.parse(xhr.responseText); Compost('/appstore/app/updateOneProperty',{'id':datascope.appid,'ios_url':plistUrl},function () { $('#ios_url').textbox('setText', plistUrl); }) console.log("plist上傳成功") } else if (xhr.status != 200 && xhr.responseText) { } }; startDate = new Date().getTime(); $("#progressbar").show(); xhr.send(formData); }; /*var reader = new window.FileReader(); reader.readAsDataURL(blob); reader.onloadend = function() { var base64data = reader.result; console.log(base64data); }*/ $.ajax({ type: "get", url: "/appstore/app/qiniuUploadToken?params=" + key + ".plist", async: true, dataType: "json", success: function (data) { var token = data.uptoken; console.log(token); Qiniu_upload(blob, token); } }); }
到此最重要的一步自動上傳plist完成!,以此共同窗習。
plupload插件支持,ipa和apk都是zip類型,因此title是Zip files
filters: { mime_types: [ {title: "Image files", extensions: "png"}, //限定png後綴上傳 {title: "Zip files", extensions: "ipa"}, //限定ipa後綴上傳 {title: "Zip files", extensions: "apk"}, //限定apk後綴上傳 ] },
每次實例化option方法時會( browse_button: *// 上傳選擇的點選按鈕,必需)給按鈕綁定一個點擊事件,因此以後會點擊打開屢次選擇文件窗口。
嘗試解決方案(失敗):銷燬option對象,銷燬對象綁定的事件不會刪除
銷燬綁定事件,因爲沒有事件名稱因此沒法刪除
嘗試解決方案(成功):
if (uploader) {uploader.disableBrowse(true);}