天天看點

SAE Storage + Android微信内置浏覽器圖檔上傳解決方案

發現需求   

最近在做一個項目,需要在微信裡打開的網頁中實作上傳,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,如需轉載請自行聯系原作者