Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript encodeURIComponent二进制字符串上的数据损坏_Javascript_Jquery_Ajax_Html_Node.js - Fatal编程技术网

Javascript encodeURIComponent二进制字符串上的数据损坏

Javascript encodeURIComponent二进制字符串上的数据损坏,javascript,jquery,ajax,html,node.js,Javascript,Jquery,Ajax,Html,Node.js,我正在使用jqueryajaxget请求读取一个二进制文件,在这里我以字符串的形式接收文件(在我的例子中是zip文件)。一旦我在浏览器中对文件执行了一些操作(而不是修改文件),我需要将其传输回服务器端点(在本例中,使用express3的nodejs),也需要通过ajax。我正试图通过以下POST请求来实现这一点,因为需要使用encodeURIComponent对我的字符串进行编码,我认为这是我遇到问题的地方: var fd = new FormData(); fd.append("filedat

我正在使用jqueryajaxget请求读取一个二进制文件,在这里我以字符串的形式接收文件(在我的例子中是zip文件)。一旦我在浏览器中对文件执行了一些操作(而不是修改文件),我需要将其传输回服务器端点(在本例中,使用express3的nodejs),也需要通过ajax。我正试图通过以下POST请求来实现这一点,因为需要使用encodeURIComponent对我的字符串进行编码,我认为这是我遇到问题的地方:

var fd = new FormData();
fd.append("filedata", encodeURIComponent(data), "filedata"); // data is my binary string
fd.append("filename", $('#url-input').val().split('/').slice(-1)[0]);
$.ajax({
    type: "POST",
    url: 'endpoint',
    data: fd,
    processData: false,
    contentType: false,
    success: function() {
        alert('save successful');
    }
});
端点包含以下代码,它将数据作为缓冲区存储在mongodb中:

app.post('/endpoint', function(req, res) {
    var newData = {};
    newData.file = new Mongo.Binary(new Buffer(decodeURIComponent(req.body.filedata), "binary"));
    newData.name = req.body.filename;
    newData.date = moment().format('MMMM Do YYYY, h:mm:ss a');
    database.insert(newData, {safe: true}, function() { console.log('inserted new data'); });
});
这看起来都是按计划进行的,但是,当我稍后检索文件时,它有点损坏。当我将其与十六进制编辑器中的原始值进行比较时,值接近但不精确,以下是两个文件部分的示例:

原始文件:

01 02 54 03 08 5D 08 5D 66 18 61 66 19 1B 67 1C 03 66 01 02 7A 85 14 80 7E 7F 81 82 85 85 80 80 85 5D 80 5D 14 80 14 80 89 8A 81 82 80 80 80 80 80 5D 80 5D 67 66 03 03 6D 6C 11 64 01 02 2E 37 57 85 57 80 85 57 80 57 57 8C 54 85 8C 8C 85 85 80 57 80 57 7A 80 14 80 8C 57 85 57 1A 8C 57 85 57 8C 57 85 18 1B 6D 1C 3E 30 15 57 37 37 6C 66 54 24 57 34 15 57 15 2E 01 2E 02 57 37 54 2C 2D 76 2E 74 77 68 6B 68 68 71 71 74 74 A7 A7 A7 A7 19 19 66 71 19 1A 08 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 DD DE 10 EE 6D 8B 7C 01 69 6A 6A 5C 10 21 7C 60 56 CC EE 02 1C 01 BE 8C 8D 8D 8D 44 AC AE 01
从发布的文件中对应的字符串,请注意它的区别仅很小:

01 02 54 03 08 5D 08 5D 66 18 61 66 19 1B 67 1C 03 66 01 02 7A FD 14 FD 7E 7F FD FD FD FD FD FD FD 5D FD 5D 14 FD 14 FD FD FD FD FD FD FD FD FD FD 5D FD 5D 67 66 03 03 6D 6C 11 64 01 02 2E 37 57 FD 57 FD FD 57 FD 57 57 FD 54 FD FD FD FD FD FD 57 FD 57 7A FD 14 FD FD 57 FD 57 1A FD 57 FD 57 FD 57 FD 18 1B 6D 1C 3E 30 15 57 37 37 6C 66 54 24 57 34 15 57 15 2E 01 2E 02 57 37 54 2C 2D 76 2E 74 77 68 6B 68 68 71 71 74 74 FD FD FD FD 19 19 66 71 19 1A 08 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
我应该注意到,我曾尝试在代码中使用其他函数,例如客户端上的btoa和服务器上的atob(带有模块),但所有这些都需要使用encodeURIComponent,我认为这是对数据的破坏。我还可以通过稍微不同的路径和传统的post表单在mongodb中存储二进制数据


还有其他人遇到过这个问题吗?

在我最初问题的一条评论中,有人提到我应该尝试使用blob来代替。我只是按照如下方式重新编写了代码,删除了jQuery用法,还使用了blob:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'endpoint for original binary file', true);
xhr.responseType = 'blob';

xhr.onload = function(e) {
    var data = this.response; // this is a blob

    var reader = new FileReader();
    reader.onload = function() {
        var dataUrl = reader.result;
        var base64 = dataUrl.split(',')[1];

        var fd = new FormData();
        fd.append("filedata", base64, "filedata");
        fd.append("filename", $('#url-input').val().split('/').slice(-1)[0]);

        var request = new XMLHttpRequest();
        request.open("POST", "endpoint");
        request.onload = function (e) {
            if (this.status === 200) {
                alert('sent');
            }
        };
        request.send(fd);
    };
    reader.readAsDataURL(data);
}
除此之外,相关服务器代码基本相同

 newData.file = new Mongo.Binary(new Buffer(decodeURIComponent(req.body.filedata), "binary"));
变成:

 newData.file = new Mongo.Binary(new Buffer(req.body.filedata, "base64"));

谢谢你的提问,这无疑帮助我找到了正确答案。

如果你不修改文件,为什么不能使用FormData正常上传文件?因为一旦这样做起作用,有些情况下会修改文件,我只是注意到,在这个例子中我没有修改文件,所以它应该与我比较的原始文件相同。JavaScript字符串不包含二进制数据,它们包含utf-16代码点或ucs-2?idk,但不是二进制的。尝试使用类型化数组或blob来处理数据。您是否可以尝试在不使用所有其他内容的情况下复制这些数据?如果
encodeURIComponent
有问题,您可以通过调用对特定字符串进行编码和解码来直接复制它。事实上,我不觉得我们有一个可以重复的案例,有人可以不加猜测地回答。对不起,我觉得我已经尽可能地把它删掉了,同时仍然在解释正在发生的一切。我将对它做更多的工作,看看是否能拿出更多的验证来证明它是一个组件。根据函数的类型,数据肯定是一个字符串。您可以将blob直接附加到FormData对象,而无需对其进行编码
fd.append(“filedata”,this.response,“filedata”)我试图这样做,但无论出于何种原因,blob没有显示在服务器上的请求主体中。一旦我对它编码,我就能看到它。它现在正在工作,但我以后可能会进一步调查,谢谢