透過 swfupload 直接上傳到 S3

由於 app engine 無法上傳大檔案, 即使使用 BlobStore 單檔最大也只能到 50MB 而已, 對於 MyAudioCast 來說, 豬小草的 Podcast 檔案幾乎都是超過 100MB, 所以看來就只能用 S3 來放檔案, 可是 app engine 的 urlfetch 也只能傳 1MB, 所以後來就直接採用 S3 提供的 form upload 的方式, 直接用 HTML POST Form 把檔案送到 S3, 有興趣的話可以看看 Browser Uploads to S3 using HTML POST Forms 這一篇文章, 所以就可以不用透過後端程式, 直接從前端上傳檔案到 S3 然後 redirect 回來。所以在這邊記錄一下。

然而這樣出現了一個問題, 沒辦法檢查上傳的檔案類型, 甚至知道檔案大小 ( 原本的作法是上傳完之後, 再去 s3 抓檔案大小的資料 ), 所以研究了一下用 swfupload 來做檔案進度顯示以及顯示, 並限制檔案的類型、大小, 同時也可以取得檔案的大小。

原本的 POST FORM 看起來像是下面這樣

<form id="upload_form" action="http://myaudiocast.s3.amazonaws.com/"  
    method="post" enctype="multipart/form-data">
<input type="hidden" name="key" value="{{ key }}" />  
<input type="hidden" name="AWSAccessKeyId" value="{{ AWS_ACCESS_KEY }}" />  
<input type="hidden" name="acl" value="{{ acl }}" />  
<input type="hidden" name="policy" value="{{ policy }}" />  
<input type="hidden" name="signature" value="{{ signature }}" />  
<input type="hidden" name="Content-Type" value="{{ content_type }}" />  
<input type="hidden" name="Cache-Control" value="{{ cache_control }}" />  
<input type="hidden" name="Expires" value="{{ expires }}" />  
<input type="hidden" name="success_action_redirect" value="{{ success_action_redirect }}" />  
...
</form>```

基本上的作法就是把原本 policy conditions 當中的 success_action_redirect 改成 success_action_status, 也就是把轉址改成吐 201 的 status code, 然後在 policy conditions 移除 success_action_redirect, 並加上下面兩個項目即可。

["starts-with", "$Filename", ""], ["eq", '$successactionstatus', "201"]

而 swfupload 的 PostParams 也是把原本要 POST 出去的欄位加上即可

swfu.setPostParams({
'key': key, 'AWSAccessKeyId': "{{ AWSACCESSKEY }}", 'acl': "{{ acl }}", 'policy': "{{ policy }}", 'signature': "{{ signature }}", 'Content-Type': "{{ contenttype }}", 'Cache-Control': "{{ cachecontrol }}", 'Expires': "{{ expires }}", 'successactionstatus': {{ successactionstatus }} });```

然後 s3 bucket 那邊也得加上一個 /crossdomain.xml, 否則 Flash 會有 security error, 檔案內容如下。

```


    
```

``

最後就是, 由於 Flash 接到 200 以外的 status code 都會視為失敗 ( 至少我查到的資訊都是這麼說 ), 所以 swfupload 接到 201 的 status code 也是會認為失敗, 所以就得再 uploadError 這個 handler 判斷 status_code 是否為 201, 如果 201 則是上傳成功, 所以這點得再注意一下, 我目前的作法是這樣。

這篇主要只是記錄一下, S3 真是好服務, 而 app engine 也很好, 不過限制太多, 得自己繞路就是了 XD

tzangms

Read more posts by this author.

Subscribe to Oceanic / 海海人生

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!