發現需求
最近在做一個項目,需要在微信裡打開的網頁中實作上傳,IOS通過簡單的上傳插件可輕松搞定,但無論是FLASH+PHP還是JS+PHP,安卓平台微信内置浏覽器始終無法上傳檔案。百度谷歌,均沒有解決方案,參看很多公衆平台的解決方案,多為推薦安卓使用者跳到外部浏覽器打開網頁,但是這樣體驗不太好,于是着手自己去解決這個問題!再後來,聽朋友說微信微社群可正常上傳圖檔,于是去研究其上傳代碼,研究發現:
微社群在用戶端用了一套比較高端的JS架構,該架構将圖檔進行data:image/jpg;base64編碼并ajax的方式傳輸到服務端,并傳回圖檔的photoid等相關資訊。伺服器端我是看不到處理的細節,不過大概了解,無非就是對圖檔進行存儲和資料庫插入等操作。于是copy下該上傳方式的前端代碼。再結合SAE Storage的相關API寫了一個上傳處理的php檔案,就很快解決了這個問題,效果不錯,部分低端部分手機有閃退現象,這個微社群也存在這種問題。魅族,三星等主流機型均完美上傳,現在來和大家分享分享。
解決方案
1.SAE Storage
Storage -> 建立domain并命名為 imagefile,直接點選建立。
2.找到Storage的API http://apidoc.sinaapp.com/sae/SaeStorage.html
upload (line 291)
将檔案上傳入存儲
注意:檔案名左側所有的'/'都會被過濾掉。
return: 寫入成功時傳回該檔案的下載下傳位址,否則傳回false
author: Elmer Zhang
access: public
string upload (string $domain, string $destFileName, string $srcFileName, [array $attr = array()], [bool$compress = false])
string $domain: 存儲域,在線上管理平台.storage頁面可進行管理
string $destFileName: 目标檔案名
string $srcFileName: 源檔案名
array $attr: 檔案屬性,可設定的屬性請參考 SaeStorage::setFileAttr() 方法
bool $compress: 是否gzip壓縮。如果設為true,則檔案會經過gzip壓縮後再存入Storage,常與$attr=array('encoding'=>'gzip')聯合使用
write (line 251)
将資料寫入存儲
string write (string $domain, string $destFileName, string $content, [int $size = -1], [array $attr = array()], [bool $compress = false])
string $destFileName: 檔案名
string $content: 檔案内容,支援二進制資料
int $size: 寫入長度,預設為不限制
這裡有兩個函數可用,一個是upload,另一個是write,經實測,用upload直接處理編碼過的圖檔會報錯,應該需要先用PHP中的 base64_decode()函數解碼再用write函數寫入sae storage上剛才建立的imagefile裡。
3.伺服器端的處理代碼如下:
PHP代碼
<?php
//感謝@韓文博1學長的代碼精煉建議
$ex = explode(",",$_POST['pic']);//分割data-url資料
$filter=explode('/', trim($ex[0],';base64'));//擷取檔案類型
$s = base64_decode(str_replace($filter[1] , '', $ex[1]));//圖檔解碼
$picname = date("YmdHis") . rand(100, 999) .'.'.$filter[1];//生成随機檔案名
$s = new SaeStorage();//執行個體化SeaStorage類
$photo_id = $s->write("imagefile",$picname,$ss);//把解碼後的圖檔寫入建立的imagefile裡,成功傳回圖檔的url
if($photo_id){ //傳回json資料到浏覽器端
$status='success';
$errCode='0';
$arr = array(
'photo_id'=>$photo_id,
'status'=>$status,
'errCode'=>$errCode);
echo json_encode($arr);
}
?>
4.前端上傳代碼登入微社群,找到發帖功能,自行chrome工具下載下傳前端代碼。
修改相應的伺服器端響應檔案(見圖中選取的部分)
5.拓展閱讀
Data URL是在本地直接繪制圖檔,不是從伺服器加載,是以節省了HTTP連接配接,起到加速網頁的作用。
文法:
data:image/jpg; 聲明資料協定及類型名稱
base64, 編碼形式為base64
/9j/4AAQSkZ…… base64編碼結果
附上Data URL的生成方法(PHP):
$img_file = file_get_contents("http://tieba.baidu.com/tb/static-common/img/dimensionCode/tb_common_2dbc.jpg");
echo base64_encode($img_file);
?>
用這種方法會加重用戶端的CPU和記憶體負擔,總之有利有弊。 針對于一些小的資料,可以在網頁中直接嵌入,而不是從外部檔案載入,比如圖檔。這樣的好處是可以減少一次http的請求,缺點是使得頁面内容變大。data類型的url格式在98年就已經提出了,現在絕大部分的浏覽器都能支援,比如使用IE6核心的國内浏覽器,chrome和firefox等,實測安卓和ios上的微信浏覽器均相容此方案。大家有什麼疑問,微網誌私信我http://weibo.com/itjaye
本文轉自ljianbing51CTO部落格,原文連結: http://blog.51cto.com/ljianbing/1607026,如需轉載請自行聯系原作者