Я хочу разрешить пользователям перетаскивать изображения со своего рабочего стола в окно браузера, а затем загружать эти изображения на сервер. Я хочу загружать каждый файл только один раз, даже если он выпал в окне несколько раз. По соображениям безопасности информация из объекта File, доступная для JavaScript, ограничена. В соответствии с msdn.microsoft.com следующие свойства могут быть только для чтения:Обнаружение, если пользователь дважды удаляет один и тот же файл в окне браузера
name
lastModifiedDate
(Сафари также подвергает size
и type
).
Пользователь может удалить два изображения с тем же именем и последним измененным датом из разных папок в окно браузера. Существует очень небольшая, но конечная вероятность того, что эти два изображения на самом деле отличаются друг от друга.
Я создал сценарий, который читает в необработанном dataURL каждого файла изображения и сравнивает его с файлами, которые ранее были отброшены в окне. Одним из преимуществ этого является то, что он может обнаруживать идентичные файлы с разными именами.
Это работает, но кажется излишним. Он также требует огромного объема данных для хранения. Я мог бы улучшить это (и добавить к overkill), сделав хэш данныхURL и сохранив это вместо этого.
Я надеюсь, что может быть более элегантный способ достижения моей цели. Что вы можете предложить?
<!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>
Я предлагаю разрешить пользователю загружать изображения без разбора (с некоторыми JS, чтобы убедиться, что они на самом деле являются изображениями). Тогда на стороне сервера вы будете делать интенсивные операции с ЦП и сравнивать файлы, чтобы убедиться, что они идентичны ... если они есть, отверните одно из изображений и сообщите об этом пользователю. Если нет, хэш их имена и сохранить их – Literphor
Спасибо за ваше предложение @Literphor. Однако в этом конкретном случае важно, чтобы на каждом изображении была только одна клиентская копия. –
'file.size' хорошо поддерживается, поэтому вы можете снизить коэффициенты больше без обработки файлов. – dandavis