我们目前正在使用幻数验证图像。既然SVG不支持幻数,那么在angularJS中验证SVG文件的好方法是什么?
这就是我们验证其他图像的方式-
angular.module('fileMimeTypeServiceModule', [])
.constant('fileMimeTypeServiceConstants', {
VALID_IMAGE_MIME_TYPE_CODES: ['FFD8FFDB', 'FFD8FFE0', 'FFD8FFE1', '474946383761', '424D', '49492A00', '4D4D002A', '89504E470D0A1A0A']
})
.factory('seFileReader', function() {
var read = function(file, config) {
var fileReader = new FileReader();
config = config || {};
fileReader.onloadend = config.onLoadEnd;
fileReader.onerror = config.onError;
fileReader.readAsArrayBuffer(file);
return fileReader;
};
return {
read: read
};
})
.factory('fileMimeTypeService', function(fileMimeTypeServiceConstants, seFileReader, $q) {
var _validateMimeTypeFromFile = function(loadedFile) {
var fileAsBytes = (new Uint8Array(loadedFile)).subarray(0, 8);
var header = fileAsBytes.reduce(function(header, byte) {
var byteAsStr = byte.toString(16);
if (byteAsStr.length === 1) {
byteAsStr = '0' + byteAsStr;
}
header += byteAsStr;
return header;
}, '');
return fileMimeTypeServiceConstants.VALID_IMAGE_MIME_TYPE_CODES.some(function(mimeTypeCode) {
return header.toLowerCase().indexOf(mimeTypeCode.toLowerCase()) === 0; // validating here
});
};
var isFileMimeTypeValid = function(file) {
var deferred = $q.defer();
seFileReader.read(file, {
onLoadEnd: function(e) {
if (_validateMimeTypeFromFile(e.target.result)) {
deferred.resolve();
} else {
deferred.reject();
}
},
onError: function() {
deferred.reject();
}
});
return deferred.promise;
};
return {
isFileMimeTypeValid: isFileMimeTypeValid
};
});
现在我也想验证SVG图像,我们如何在没有幻数的情况下验证它?
SVG图像是XML文件。在第一步中,您可以测试XML幻数。之后,您可以将文件内容读取为文本,并使用DOMParser进行解析。如果发生错误,这将告诉您该文件无效。
此示例使用TextDecoder API将数组缓冲区转换为字符串。这可能比使用单独的异步FileReader.readAsText()
操作更具限制性。您应该检查浏览器兼容性,以确定此解决方案是否足够好。
angular.module('fileMimeTypeServiceModule', [])
.constant('fileMimeTypeServiceConstants', {
VALID_IMAGE_MIME_TYPE_CODES: [ 'ffd8ffdb', 'ffd8ffe0', 'ffd8ffe1', '474946383761', '424d', '49492a00', '4d4d002a', '89504e470d0a1a0a' ],
XML_MIME_TYPE_CODE: '3c3f786d6c'
})
.factory('seFileReader', function() {/*...*/})
.factory('fileMimeTypeService', function(fileMimeTypeServiceConstants, seFileReader, $q) {
var _validateMimeTypeFromFile = function(loadedFile) {
var u8arr = new Uint8Array(loadedFile);
var fileAsBytes = (u8arr).subarray(0, 8);
var header = fileAsBytes.reduce(function(header, byte) {
var byteAsStr = byte.toString(16);
if (byteAsStr.length === 1) {
byteAsStr = '0' + byteAsStr;
}
header += byteAsStr;
return header;
}, '');
if (header.toLowerCase().startsWith(fileMimeTypeServiceConstants.XML_MIME_TYPE_CODE) {
try {
var fileContentAsString = new TextDecoder('utf-8').decode(u8arr);
var parser = new DOMParser();
parser.parseFromString(fileContentAsString, 'image/svg+xml');
return true;
} catch (e) {
return false;
}
} else {
return fileMimeTypeServiceConstants.VALID_IMAGE_MIME_TYPE_CODES.some(function(mimeTypeCode) {
return header.toLowerCase().startsWith(mimeTypeCode);
});
}
};
//...
});
显然,如果您希望测试非常大的文件,这可能是一个消耗内存的操作,因为SVG的完整DOM已经构建(但没有呈现(。我的期望是,对于除了一些异常用例之外的所有用例,比如并行测试大量文件,它仍然是最快、最可靠的解决方案。