Tôi muốn cho phép người dùng kéo hình ảnh từ màn hình của họ lên cửa sổ trình duyệt rồi tải những hình ảnh đó lên máy chủ. Tôi muốn tải lên từng tệp một lần, ngay cả khi nó bị bỏ trên cửa sổ nhiều lần. Vì lý do bảo mật, thông tin từ đối tượng Tệp có thể truy cập JavaScript bị giới hạn. Theo msdn.microsoft.com, chỉ có các tính chất sau đây có thể được đọc:Phát hiện xem người dùng có thả cùng một tệp hai lần trên cửa sổ trình duyệt không
name
lastModifiedDate
(Safari cũng cho thấy nhiều size
và type
).
Người dùng có thể thả hai hình ảnh có cùng tên và ngày sửa đổi lần cuối từ các thư mục khác nhau vào cửa sổ trình duyệt. Có một cơ hội rất nhỏ nhưng hữu hạn mà hai hình ảnh này trong thực tế khác nhau.
Tôi đã tạo tập lệnh đọc trong dataURL thô của mỗi tệp hình ảnh và so sánh tập lệnh đó với các tệp đã bị xóa trước đó trên cửa sổ. Một lợi thế của việc này là nó có thể phát hiện các tệp giống hệt nhau với các tên khác nhau.
Công trình này, nhưng có vẻ như quá mức. Nó cũng đòi hỏi một lượng lớn dữ liệu được lưu trữ. Tôi có thể cải thiện điều này (và thêm vào overkill) bằng cách tạo một hash của dataURL và lưu trữ thay vào đó.
Tôi hy vọng rằng có thể có một cách thanh lịch hơn để đạt được mục tiêu của mình. Những gì bạn có thể đề nghị?
<!DOCTYPE html>
<html>
<head>
<title>Detect duplicate drops</title>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
background: #000;
}
</style>
<script>
var body
var imageData = []
document.addEventListener('DOMContentLoaded', function ready() {
body = document.getElementsByTagName("body")[0]
body.addEventListener("dragover", swallowEvent, false)
body.addEventListener("drop", treatDrop, false)
}, false)
function swallowEvent(event) {
// Prevent browser from loading the dropped image in an empty page
event.preventDefault()
event.stopPropagation()
}
function treatDrop(event) {
swallowEvent(event)
for (var ii=0, file; file = event.dataTransfer.files[ii]; ii++) {
importImage(file)
}
}
function importImage(file) {
var reader = new FileReader()
reader.onload = function fileImported(event) {
var dataURL = event.target.result
var index = imageData.indexOf(dataURL)
var img, message
if (index < 0) {
index = imageData.length
console.log(dataURL)
imageData.push(dataURL, file.name)
message = "Image "+file.name+" imported"
} else {
message = "Image "+file.name+" imported as "+imageData[index+1]
}
img = document.createElement("img")
img.src = imageData[index] // copy or reference?
body.appendChild(img)
console.log(message)
}
reader.readAsDataURL(file)
}
</script>
</head>
<body>
</body>
</html>
Tôi khuyên bạn nên cho phép người dùng tải lên hình ảnh một cách bừa bãi (với một số JS để đảm bảo rằng chúng thực sự là hình ảnh). Sau đó, phía máy chủ, bạn sẽ thực hiện các hoạt động chuyên sâu của CPU và so sánh các tệp để xem chúng có giống nhau hay không ... nếu chúng là, từ chối một trong các hình ảnh và thông báo cho người dùng. Nếu không, hãy băm tên và lưu trữ chúng – Literphor
Cảm ơn đề xuất của bạn, @Literphor. Tuy nhiên, trong trường hợp cụ thể này, điều quan trọng là chỉ nên có một bản sao phía máy khách của mỗi hình ảnh. –
'file.size' được hỗ trợ tốt, vì vậy bạn có thể giảm tỷ lệ cược mà không cần xử lý dữ liệu tệp. – dandavis