無重新整理上傳檔案以及HTML5下的實現方式
常規實現方法:
ajax無法實現上傳檔案,因此常規情況下,要實現無重新整理上傳檔案的做法,是在頁面隱藏一個iframe,然後將上傳form的target指向這個iframe,變相的實現。如下程式碼:
1
2
3
4
5
6
7
|
< p id = "uploading" style = "display:none;" >Uploading...< img src = "loading.gif" />
< form action = "upload.php" method = "post" enctype = "multipart/form-data" target = "upload_target" onsubmit = "startUpload();" >
File: < input name = "myfile" type = "file" />
< input type = "submit" name = "submitBtn" value = "Upload" />
</ form >
< iframe id = "upload_target" name = "upload_target" src = "#" style = ";height:0;border:0px solid #fff;" >
</ iframe >
|
upload_target是一個長寬都是0的iframe,所以頁面上看不見他。還需要配合js,使得效果更好:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<script> function startUpload(){
$( `#uploading` ).show();
} function finisheUpload(i){
$( `#uploading` ).hide();
if (i== 0 )
{
alert( "上傳成功" );
}
else
{
alert( "上傳失敗" );
}
} </script> |
其中startUpload方法是在提交表單的時候觸發,而由於沒有什麼回撥函式,因此finisheUpload只能由upload.php檔案的輸出控制。通常就是在輸出中輸出一段javascript程式碼來執行。
php程式碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php header( "Content-Type:text/html;charset=utf-8" );
$destination_path = getcwd ().DIRECTORY_SEPARATOR;
$filname = $destination_path . basename ( $_FILES [ `myfile` ][ `name` ]);
$filname =iconv( "UTF-8" , "gb2312" , $filname );
if (move_uploaded_file( $_FILES [ `myfile` ][ `tmp_name` ], $filname )) {
echo "<script language="javascript" type="text/javascript">window.parent.finisheUpload(0);</script> " ;
} else { echo "<script language="javascript" type="text/javascript">window.parent.finisheUpload(1);</script> " ;
} |
注意,輸出javascript的時候,由於呼叫的js方法是在iframe外定義的,要在iframe內呼叫js方法,需要指定window.parent。
————————
HTML5下的實現方法:
先介紹一下FileReader物件:
FileReader物件的詳細說明可以在W3C官方文件中檢視。
該介面提供方法來讀取檔案物件或者Blob物件。它繼承了EventTarget,介面的描述如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
[Constructor] interface FileReader: EventTarget {
// async read methods
void readAsArrayBuffer(Blob blob);
void readAsText(Blob blob, optional DOMString label);
void readAsDataURL(Blob blob);
void abort();
// states
const unsigned short EMPTY = 0 ;
const unsigned short LOADING = 1 ;
const unsigned short DONE = 2 ;
readonly attribute unsigned short readyState;
// File or Blob data
readonly attribute (DOMString or ArrayBuffer)? result;
readonly attribute DOMError? error;
// event handler attributes
attribute EventHandler attribute EventHandler onprogress;
attribute EventHandler attribute EventHandler onabort;
attribute EventHandler onerror;
attribute EventHandler };
|
可以看到有4個非同步方法,其中3個是讀取,1個是放棄,4個狀態屬性,1個result,1個error和6個事件。(之前還有readAsBinaryString方法,不過已經被W3C去除了)這6個事件的觸發時機如下:
loadstart –When the read starts.
progress –While reading (and decoding) blob
abort –When the read has been aborted. For instance, by invoking the abort() method.
error –When the read has failed (see errors).
load –When the read has successfully completed.
loadend –When the request has completed (either in success or failure).
下面演示一個例子,讀取一個文字文件,並且alert出來內容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<script> function readfile(dom)
{ var file = dom.files[0];
var textType = /text.*/; //正規表示式,使之匹配text/html,text/plain
if (file.type.match(textType)) {
var reader = new FileReader();
//註冊事件函式,即等讀完內容後,要做的事情
reader.onload = function (e) {
alert(reader.result);
}
//非同步讀取內容
reader.readAsText(file, `gb2312` );
$( "#msg" ).html( "正在執行非同步讀取" );
}
else {
alert( "檔案不支援" );
}
} </script> <input type= "file" id= "testfiles" name= "files[]" onchange= "readfile(this);" />
<div id= "msg" ></div>
|
——————————————————————————————
下面演示一個例子,讀取一個DataURL的,DataURL其實是一種DataURI(要知道URI的更多細節,可以去http://css-tricks.com/data-uris/,或者維基百科瞭解更多)。它提供了一種在瀏覽器中顯示資料的途徑。比如你要顯示一個圖片(百度的logo)的話,你可以如下寫:
1
|
< img src = "http://www.baidu.com/img/bdlogo.gif" />
|
你也可以用它的URI去寫,如下:
<img src=”data:image/gif;base64,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″ />
src中填寫的字串就是DataURI,格式如下:
data:[<mime type>][;charset=<charset>][;base64],<encoded data>
這種URI其實很有用的,可以減少HTTP請求,使得網站提速。因此獲取了URI的話就可以載入本地的影像了。示例程式碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<script> function loadimg(dom)
{ var file = dom.files[0];
//正規表示式,使之匹配image/jpeg等
var imageType = /image.*/;
if (file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function (e) {
var img = new Image();
img.src = reader.result;
$( "#divimg" ).append(img);
}
reader.readAsDataURL(file);
}
else {
alert( "檔案不支援" );
}
} </script> <input type= "file" id= "testfiles" name= "files[]" onchange= "loadimg(this);" />
<div id= "divimg" ></div>
|
————————————————————————————————————
還有一個方法是readAsArrayBuffer,從字面就可以看出,是把檔案讀取到一個陣列緩衝區。
使用readAsArrayBuffer這種方法實現上傳檔案
下面演示一個例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<script> function upload()
{ var file = $( `#testfiles` )[0].files[0];
var reader = new FileReader();
reader.onload = function (rResult) {
var filename = file.name;
var options = {
type: `POST` ,
url: `upload.php?filename=` +filename,
data: reader.result,
success: function (result){
alert(result.msg);
},
processData: false , // 告訴jQuery不要去處理髮送的資料
contentType: false , // 告訴jQuery不要去設定Content-Type請求頭
dataType: "json"
};
$.ajax(options);
};
reader.readAsArrayBuffer(file);
} </script> <input type= "button" value= "upload" onclick= "javascript:upload();" />
|
後端PHP程式碼:
1
2
3
4
5
6
7
8
9
10
|
try {
$filename = $_GET [ `filename` ];
$input = file_get_contents ( "php://input" ); //這個是獲取請求的InputStream,PHP下的寫法
file_put_contents ( $filename , $input ); //儲存成檔案。
echo json_encode( array ( "msg" => "上傳成功" ));
} catch (Exception $e )
{ echo json_encode( array ( "msg" => "上傳失敗" ));
} |
FormData方法
FromData的官方說明在這裡。利用FormData
物件,你可以使用一系列的鍵值對來模擬一個完整的表單。
以下給出一個例子,允許上傳多個檔案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<script> function upload()
{ var formdata = new FormData();
$.each($( `#testfiles` )[0].files, function (i, file) {
formdata.append( `file-` +i, file);
});
var options = {
type: `POST` ,
url: `upload.php` ,
data: formdata,
success: function (result){
alert(result.msg);
},
processData: false , // 告訴jQuery不要去處理髮送的資料
contentType: false , // 告訴jQuery不要去設定Content-Type請求頭
dataType: "json"
};
$.ajax(options);
} </script> <input type= "button" value= "upload" onclick= "javascript:upload();" />
|
後臺PHP程式碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
try { foreach ( $_FILES as $key => $value )
{
//print_r ($_FILES[$key]); echo "<br>";
move_uploaded_file( $value [ "tmp_name" ], $value [ `name` ]);
}
echo json_encode( array ( "msg" => "上傳成功" ));
} catch (Exception $e )
{ echo json_encode( array ( "msg" => "上傳失敗" ));
} |
參考文件:
https://developer.mozilla.org/zh-CN/docs/DOM/XMLHttpRequest/FormData/Using_FormData_Objects
http://dev.w3.org/2006/webapi/FileAPI/#FileReader-interface
http://www.w3.org/TR/XMLHttpRequest2/#interface-formdata
http://blog.teamtreehouse.com/reading-files-using-the-html5-filereader-api
本文轉自cnn23711151CTO部落格,原文連結:http://blog.51cto.com/cnn237111/1330089,如需轉載請自行聯絡原作者
相關文章
- Feign實現檔案上傳下載
- 重新整理檔案上傳
- SpringMVC實現檔案上傳&下載(2)SpringMVC
- vue實現Excel檔案的上傳與下載VueExcel
- HTML5拖拽檔案上傳HTML
- 前端實現檔案下載和拖拽上傳前端
- ajax實現檔案上傳
- PHP實現單檔案、多檔案上傳 封裝 物件導向實現檔案上傳PHP封裝物件
- js下載檔案的實現方式JS
- jquery ajax file upload NET MVC 無重新整理檔案上傳jQueryMVC
- 檔案上傳的幾種方式
- js實現帶上傳進度的檔案上傳JS
- JavaWeb之實現檔案上傳與下載工具JavaWeb
- JavaWeb之實現檔案上傳與下載元件JavaWeb元件
- JavaWeb之實現檔案上傳與下載示例JavaWeb
- React中使用fetch實現檔案上傳下載React
- 使用java的MultipartFile實現layui官網檔案上傳實現全部示例,java檔案上傳JavaUI
- 使用Vue+go實現前後端檔案的上傳下載,csv檔案上傳下載可直接照搬VueGo後端
- Spring 對檔案上傳下載的支援(Spring boot實現)Spring Boot
- Spring mvc檔案上傳實現SpringMVC
- HttpFileCollection 實現多檔案上傳HTTP
- 檔案上傳原理和實現
- 使用Spring實現上傳檔案Spring
- Spring Cloud Feign的檔案上傳實現SpringCloud
- 網路隔離下實現的檔案傳輸,現有的方式真的安全嗎?
- 教你如何實現c#檔案上傳下載功能C#
- JavaWeb之實現檔案上傳與下載外掛JavaWeb
- JavaWeb之實現檔案上傳與下載原始碼JavaWeb原始碼
- JavaWeb之實現檔案上傳與下載例項JavaWeb
- 通過配置檔案(.htaccess)實現檔案上傳
- 實現簡單的csv檔案上傳和bootstrap表格的下載boot
- PHP實現圖片(檔案)上傳PHP
- SpringMVC多個檔案上傳實現SpringMVC
- Java檔案上傳如何實現呢?Java
- 關於node實現檔案上傳
- springCloud 微服務通過minio實現檔案上傳和檔案下載介面SpringGCCloud微服務
- 檔案上傳下載
- JavaWeb之實現檔案上傳與下載控制元件JavaWeb控制元件
- 檔案的上傳與下載