FileReader
Bir sunucuya yüklemeden önce MIME türünü JavaScript'lerle kolayca belirleyebilirsiniz . İstemci tarafı üzerinden sunucu tarafı kontrolünü tercih etmemiz gerektiğini kabul ediyorum, ancak istemci tarafı kontrolü hala mümkün. Size nasıl olduğunu göstereceğim ve en altta çalışan bir demo sunacağım.
Tarayıcınızın hem File
ve hem de desteklediğinden emin olun Blob
. Tüm büyük olanlar gerekir.
if (window.FileReader && window.Blob) {
// All the File APIs are supported.
} else {
// File and Blob are not supported
}
Aşama 1:
File
Bilgileri <input>
böyle bir elemandan alabilirsiniz ( ref ):
<input type="file" id="your-files" multiple>
<script>
var control = document.getElementById("your-files");
control.addEventListener("change", function(event) {
// When the control has changed, there are new files
var files = control.files,
for (var i = 0; i < files.length; i++) {
console.log("Filename: " + files[i].name);
console.log("Type: " + files[i].type);
console.log("Size: " + files[i].size + " bytes");
}
}, false);
</script>
Yukarıdakilerin sürükle ve bırak versiyonu ( ref ):
<div id="your-files"></div>
<script>
var target = document.getElementById("your-files");
target.addEventListener("dragover", function(event) {
event.preventDefault();
}, false);
target.addEventListener("drop", function(event) {
// Cancel default actions
event.preventDefault();
var files = event.dataTransfer.files,
for (var i = 0; i < files.length; i++) {
console.log("Filename: " + files[i].name);
console.log("Type: " + files[i].type);
console.log("Size: " + files[i].size + " bytes");
}
}, false);
</script>
Adım 2:
Artık dosyaları inceleyebilir ve üstbilgileri ve MIME türlerini alay edebiliriz.
Method Hızlı yöntem
Bu kalıbı kullanarak Blob'un MIME türünü temsil ettiği herhangi bir dosyayı isteyebilirsiniz.
var blob = files[i]; // See step 1 above
console.log(blob.type);
Görüntüler için MIME türleri aşağıdaki gibi geri gelir:
görüntü / jpeg
görüntü / png
...
Uyarı: MIME türü dosya uzantısından algılanır ve aldatılabilir veya aldatılabilir. Birini a .jpg
olarak yeniden adlandırabilir .png
ve MIME türü olarak bildirilir image/png
.
✓ Uygun başlık inceleme yöntemi
İstemci tarafı bir dosyanın bonafide MIME türünü elde etmek için bir adım daha ileri gidebilir ve söz konusu dosyanın ilk birkaç baytını sihirli sayılarla karşılaştırmak için inceleyebiliriz . Bunun tamamen açık olmadığı konusunda uyarıda bulunun, örneğin JPEG'de birkaç "sihirli sayı" vardır. Bunun nedeni, biçimin 1991'den beri gelişmesidir. Yalnızca ilk iki baytı kontrol etmekten kurtulabilirsiniz, ancak yanlış pozitifleri azaltmak için en az 4 bayt kontrol etmeyi tercih ederim.
JPEG örnek dosya imzaları (ilk 4 bayt):
FF D8 FF E0 (SOI + ADD0)
FF D8 FF E1 (SOI + ADD1)
FF D8 FF E2 (SOI + ADD2)
İşte dosya üstbilgisini almak için gerekli kod:
var blob = files[i]; // See step 1 above
var fileReader = new FileReader();
fileReader.onloadend = function(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var header = "";
for(var i = 0; i < arr.length; i++) {
header += arr[i].toString(16);
}
console.log(header);
// Check the file signature against known types
};
fileReader.readAsArrayBuffer(blob);
Daha sonra gerçek MIME türünü bu şekilde belirleyebilirsiniz ( burada ve burada daha fazla dosya imzası ):
switch (header) {
case "89504e47":
type = "image/png";
break;
case "47494638":
type = "image/gif";
break;
case "ffd8ffe0":
case "ffd8ffe1":
case "ffd8ffe2":
case "ffd8ffe3":
case "ffd8ffe8":
type = "image/jpeg";
break;
default:
type = "unknown"; // Or you can use the blob.type as fallback
break;
}
Beklenen MIME türlerine göre dosya yüklemelerini istediğiniz gibi kabul edin veya reddedin.
gösteri
İşte yerel dosyalar ve uzak dosyalar için çalışan bir demo (Ben sadece bu demo için CORS atlamak zorunda kaldı). Parçacığı açın, çalıştırın ve farklı türde üç uzak resim görüntülendiğini görmelisiniz. Üstte yerel bir görüntü veya veri dosyası seçebilirsiniz ve dosya imzası ve / veya MIME türü görüntülenir.
Bir görüntü yeniden adlandırılsa bile, gerçek MIME türünün belirlenebileceğine dikkat edin. Aşağıya bakınız.
Ekran görüntüsü
// Return the first few bytes of the file as a hex string
function getBLOBFileHeader(url, blob, callback) {
var fileReader = new FileReader();
fileReader.onloadend = function(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var header = "";
for (var i = 0; i < arr.length; i++) {
header += arr[i].toString(16);
}
callback(url, header);
};
fileReader.readAsArrayBuffer(blob);
}
function getRemoteFileHeader(url, callback) {
var xhr = new XMLHttpRequest();
// Bypass CORS for this demo - naughty, Drakes
xhr.open('GET', '//cors-anywhere.herokuapp.com/' + url);
xhr.responseType = "blob";
xhr.onload = function() {
callback(url, xhr.response);
};
xhr.onerror = function() {
alert('A network error occurred!');
};
xhr.send();
}
function headerCallback(url, headerString) {
printHeaderInfo(url, headerString);
}
function remoteCallback(url, blob) {
printImage(blob);
getBLOBFileHeader(url, blob, headerCallback);
}
function printImage(blob) {
// Add this image to the document body for proof of GET success
var fr = new FileReader();
fr.onloadend = function() {
$("hr").after($("<img>").attr("src", fr.result))
.after($("<div>").text("Blob MIME type: " + blob.type));
};
fr.readAsDataURL(blob);
}
// Add more from http://en.wikipedia.org/wiki/List_of_file_signatures
function mimeType(headerString) {
switch (headerString) {
case "89504e47":
type = "image/png";
break;
case "47494638":
type = "image/gif";
break;
case "ffd8ffe0":
case "ffd8ffe1":
case "ffd8ffe2":
type = "image/jpeg";
break;
default:
type = "unknown";
break;
}
return type;
}
function printHeaderInfo(url, headerString) {
$("hr").after($("<div>").text("Real MIME type: " + mimeType(headerString)))
.after($("<div>").text("File header: 0x" + headerString))
.after($("<div>").text(url));
}
/* Demo driver code */
var imageURLsArray = ["http://media2.giphy.com/media/8KrhxtEsrdhD2/giphy.gif", "http://upload.wikimedia.org/wikipedia/commons/e/e9/Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png", "http://static.giantbomb.com/uploads/scale_small/0/316/520157-apple_logo_dec07.jpg"];
// Check for FileReader support
if (window.FileReader && window.Blob) {
// Load all the remote images from the urls array
for (var i = 0; i < imageURLsArray.length; i++) {
getRemoteFileHeader(imageURLsArray[i], remoteCallback);
}
/* Handle local files */
$("input").on('change', function(event) {
var file = event.target.files[0];
if (file.size >= 2 * 1024 * 1024) {
alert("File size must be at most 2MB");
return;
}
remoteCallback(escape(file.name), file);
});
} else {
// File and Blob are not supported
$("hr").after( $("<div>").text("It seems your browser doesn't support FileReader") );
} /* Drakes, 2015 */
img {
max-height: 200px
}
div {
height: 26px;
font: Arial;
font-size: 12pt
}
form {
height: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form>
<input type="file" />
<div>Choose an image to see its file signature.</div>
</form>
<hr/>
I want to perform a client side checking to avoid unnecessary wastage of server resource.
Doğrulamanın neden sunucu tarafında yapılması gerektiğini söylediğinizi anlamıyorum, ancak sunucu kaynaklarını azaltmak istediğinizi söylüyorum. Altın kural: Kullanıcı girişine asla güvenme . O zaman sadece sunucu tarafında yapıyorsanız, istemci tarafında MIME türünü kontrol etmenin anlamı nedir. Şüphesiz bu, " istemci kaynağının gereksiz bir israfı " mıydı?