我们如何在不使用AngularJS中使用幻数的情况下验证SVG图像 [英] How can we validate SVG Image without using magic number in AngularJS

查看:71
本文介绍了我们如何在不使用AngularJS中使用幻数的情况下验证SVG图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们当前正在使用幻数验证图像.由于SVG不支持幻数,在angularJS中验证SVG文件的好方法是什么?

We are currently validating images using magic number. Since SVG doesn't support magic number, what is the good way to validate SVG files in angularJS ?

这就是我们验证其他图像的方式-

This is how we are validating other images -

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图像,我们如何在没有幻数的情况下对其进行验证?

Now i want to validate SVG images as well, how can we validate it without magic number ?

推荐答案

SVG图像是XML文件.第一步,您可以测试XML幻数.之后,您可以将文件内容读取为文本,并使用 DOMParser .如果发生错误,则会告诉您该文件无效.

SVG images are XML files. In a first step, you can test for the XML magic number. Afterwards, you could read the file content as text and parse it with DOMParser. If an error occurs, this will tell you the file was invalid.

此示例使用 TextDecoder API来转换数组缓冲区到字符串.与使用单独的异步 FileReader.readAsText()操作执行此操作相比,此操作可能会有更多限制.您应该查看浏览器的兼容性,以了解该解决方案是否足够好.

This example uses the TextDecoder API to convert the array buffer to string. This might be a bit more restricting than doing it with a separate async FileReader.readAsText() operation. You should review browser compatibility to find out if this solution is good enough.

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已构建(但未呈现).我的期望是,对于某些异常的用例(例如并行测试大量文件),它仍然是所有问题中最快,最可靠的解决方案.

Obviously, this could be a memory-consuming operation if you expect to test very large files, as the complete DOM for the SVG is constructed (but not rendered). My expectation would be that it is still the fastest and most reliable solution for all but some outlier use cases, like testing a large number of files in parallel.

这篇关于我们如何在不使用AngularJS中使用幻数的情况下验证SVG图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆