問題1:
在判斷圖片是否已經上傳過,我是用$.inArray(fileLists[i].name,title)來做判斷,但是如果是不同名稱,但卻是同一張圖時我就無法判斷了。有什麼其他方法嗎?
相同圖片為:完全相同的檔案(二進位序列),只是檔案名稱不同
問題2:
使用FormData上傳時,一定只能一次傳遞一張嗎?這樣我傳遞10張不就要向server請求10次嗎?有沒有更好的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.delete{
width:20px;
height:20px;
}
.thumb {
display:block;
height: 75px;
border: 1px solid #000;
margin:auto;
margin-top:10px;
}
span{
display:inline-block;
position:relative;
width:150px;
height:150px;
background-color:#ddd;
margin-right:10px;
}
.delete{
position:absolute;
right:10px;
}
.img-div img {
height:100px;
float: left;
}
.drop-left,.drop-right {
width: 50px;
height: 200px;
float: left;
background-color:#ddd;
}
</style>
</head>
<body>
<div id='a' class="upfile-list-mes" ></div>
<form method="post" action="<?php $_SERVER['PHP_SELF'] ?>" enctype="multipart/form-data">
<input type="file" id="files" name="files[]" multiple size="40" class="image" accept="image/gif, image/jpeg, image/png">
<output id="list"></output>
<input type="hidden" name="MM_Update" value="adminAdd" >
</form>
<button id="btn">上傳</button>
<script src="../js/jquery.js"></script>
<script>
var fileInput = document.getElementById('files');
var fileLists = [];
var files;
$('#files').on('change', function(event) {
files = fileInput.files; //重新取得[input type='file']資料
//console.log(files);
files = Array.prototype.slice.call(files); //將偽數組轉成陣列
//console.log(files);
fileLists = fileLists.concat(files); //重複的圖片還是會加在後面
//console.log(fileLists.length);
//console.log(fileLists);
//顯示圖片資訊
if (files.length !== 0) {
var html = '';
var title = [];
$('img').each(function(){ //取得img的title值
title.push($(this).attr('title'));
//console.log(title);
});
for (var i = 0; i < fileLists.length; i++) {
if($.inArray(fileLists[i].name,title) == -1){ //檢查是否已有圖片 $.inArray('要找的值','指定陣列') 回傳key值 沒有該值則回傳-1
var reader = new FileReader(); //FileReader 為預設物件,用來讀取檔案
//console.log(reader);
//Closure to capture the file information.
//console.log(fileLists[i]);
reader.onload = (function(theFile) { //讀取檔案後觸發onload
return function(e) {
// Render thumbnail.
var div = document.createElement('div');
div.className = 'img-div';
div.innerHTML = [ '<div class="drop-left"></div>'+
'<img src="', e.target.result,
'" title="', escape(theFile.name), '"/>'+
'<div class="drop-right"></div>'
].join('');
//console.log(e.target.result);
//console.log(escape(theFile.name));
document.getElementById('a').insertBefore(div, null);
};
})(fileLists[i]);
reader.readAsDataURL(fileLists[i]); //讀取檔案後執行load事件
}else{
}
}
}
});
/*刪除要上傳文件*/
$('.img-div').on('click', '.delete', function(event) {
var index = $(this).parent().index(); //index(),取得元素位置
$(this).parent().css('display', 'none');
fileLists.splice(index, 1); //修改fileLists,splice(刪除項目的起始位置,刪除的個數,要添加的項目)
console.log(fileLists);
});
</script>
<script>
$('.img-div').on('click','.thumb',function(){
console.log(fileLists);
})
</script>
<script>
$("#a").mousedown(function(){
// 正在拖動的圖片的父級DIV
var $srcImgDiv = null;
// 開始拖動
$("#a .img-div img").bind("dragstart", function() {
$srcImgDiv = $(this).parent(); //選定拖動的父物件
});
// 拖動到.drop-left,.drop-right上方時觸發的事件
$("#a .drop-left,.drop-right").bind("dragover", function(event) {
event.preventDefault(); // 阻擋預設行為
});
// 結束拖動放開滑鼠的事件
$("#a .drop-left").bind("drop", function(event) {
event.preventDefault();
if($srcImgDiv[0] != $(this).parent()[0]) {
$(this).parent().before($srcImgDiv); //在前面加入圖片
}
});
$("#a .drop-right").bind("drop", function(event) {
event.preventDefault();
if($srcImgDiv[0] != $(this).parent()[0]) {
$(this).parent().after($srcImgDiv); //在後面加入圖片
}
});
});
</script>
<script>
var a = 1;
$('#btn').on('click',function(){
let img_array = [];
$('img').each(function(){ //取得img的title值
img_array.push($(this).attr('title'));
});
for(let i=0; i<img_array.length; i++){
var save_path = "../files/Images/";
var form_data = new FormData();
var files = fileLists[i]; //檔案
var files_name = fileLists[i]['name']; //檔案名稱
var key = $.inArray(files_name, img_array); //抓取該檔案在顯示時所排列的位置(陣列的key值)
//console.log(key);
form_data.append("file",files);
form_data.append("key",key);
form_data.append("save_path",save_path);
$.ajax({
type: "post",
url: "uploadFile.php",
data : form_data,
cache : false,
processData : false,
contentType : false,
dataType : 'html',
}).done(function(data){
if(1){
console.log(data);
}
});
}
});
</script>
</body>
</html>
這個舊題目我剛好有些想法提供給樓主參考,
判斷上傳圖片是否重覆的動作交由client端的javasriptp處理,
思路是這樣的,在input file選了要上傳的圖片後,會把它放進canvas,
再把canvas的data存到陣列imgArray,
只要是有重選input file就會把當前canvas data去跟陣列的最末一筆比較,
完全相同的代表重覆上傳了,這個方式是用圖片內容去比較,
結果應該是相對準確一些的(相對於比檔案名稱,檔案size來說),
範例如下:
http://www.web3d.url.tw/demo/USER/ccutmis/upload-image-into-canvas/
非常感謝,我目前看大家建議,所以我還是把檢查是否重複功能拿掉了,因為顯示跟files兩邊還要一致,故目前是取消檢查是否重複的功能。
大大的上傳相同圖片時,好像已經被預設功能阻擋了
非同步跟同步上傳那篇,因為原先寫這個圖片上傳,在上傳時還需處理圖片順序,且還需要用PHP去制定一個固定的大小,並且是一張一張上傳,所以使用了AJAX,但是因為上傳時不只有圖片,還有其他表單。這樣兩邊合併我目前不知道該如何下手,麻煩大大給小弟一點方向 謝謝
大大的上傳相同圖片時,好像已經被預設功能阻擋了
你要測試的圖檔不是直接上傳同一張圖片
而是把一張圖片複制貼上產生不同名同內容的檔
(例如 a.png 跟 a-複制.png),
然後分別上傳a.png 跟 a-複制.png才能看出效果,
input file本身機制是如果你上傳檔案的路徑沒變
它會認為是沒有變動。
另外我在這邊把每次上傳結果都存入imgArray,但只比對陣列最末筆跟目前最新上傳的image data是否一致,如果是要比對更之前的有沒有重覆就是加上廻圈把imgArray遍歷比對一遍,如果有重覆的就return true; 當然這個就要你自己寫了,有需要的這麼做的話。
這邊比對的部份都還在是客戶端,所以可以把實際上傳的AJAX寫到判斷是否重覆的區塊裡面,沒有重覆的再執行上傳到伺服器端的動作,減輕伺服器負擔。
問題1:
這個問題你問的很籠統,你要知道程式其實是很笨的。
就算你選到了同一張圖在兩個input file上。在上傳它還是將其視為兩張圖上傳。並不會幫你統合。
所以解決的重點就是看要先前處理還是後置處理。不要妄想在上傳期間處理。
前置處理就是要從其input file下手。一但選定檔案後,你可以用程式來獲取選擇檔案的路徑。
利用其資料來額外程式化處理判斷並警告其重覆選擇了。
問題2
認真來說,其實原本就可以同時上傳了。只是你的程式碼是設計成一個input上傳一次。
讓你誤解成一次一個。
但其實這樣做的目的,是為了要避免一些限制。
你要知道,其實web server有所謂的最大上傳容量限制及單檔容量限制。
一次10張圖片總合容量 10mb
跟分10次上傳一張圖片 各自1mb,共10mb。
第一種就很容易被原預設值最大上傳容量2mb給檔下來。
但第二種並不會被檔下來。
所以在一般設計上,很少會做一次性上傳的原因在此。
我相信你的程式碼也是抄過來的。但你並不清楚其原理。
當然,如果你想要一次性上傳的話。你的上傳物件就得要重新改寫一下。讓它可以一次性的將file給同時處理。這手法我就不教了。簡單點的就是直接用submit的方式。
如要用ajax的方式,要改的東西很多喔!!
一般有好幾個做法。
比較單純點的就是直接從php內下手。
畢竟有無上傳成功,php一定可以知道。
且一般上傳的流程,因該是會先將上傳的檔案放到tmp的目錄內。
再用其php的file來讀取暫存檔後再轉存。
如未上傳功,其php 的 file。也會出現對應的狀態及訊息。
你就可以借此來判斷是否成功與否返回訊息給ajax處理就好。
另外一種方式屬於利用Progress來讀取。也就是獲取瀏覽器的Progress的資料跟訊息來判斷是否有成功。大多數前端都會利用此特性來做上傳進度的處理。
確認上傳完成的話,我自己嘗試過的兩種方式
1.監聽xhr顯示進度條(網路上有滿多範例可以參考的)
2.後端寫入後再回傳訊息到前端
星大,問題1,如果是用路徑不同檔名相同檔案還是無法判定吧?有沒有其他方法呢?