gpt4 book ai didi

javascript - XMLHttpRequest:多部分/相关 POST,以 XML 和图像作为有效负载

转载 作者:可可西里 更新时间:2023-11-01 02:02:25 24 4
gpt4 key购买 nike

我正在尝试从 Chrome 扩展中将图像(带有元数据)发布到 Picasa Webalbums。请注意,如我所述 here,具有 Content-Type image/xyz 的常规帖子有效.但是,我希望包括描述/关键字和 protocol specification描述了一个 multipart/related format带有 XML 和数据部分。

我通过 HTML5 FileReader 和用户文件输入获取数据。我检索一个二进制文件字符串使用

FileReader.readAsBinaryString(file);

假设这是我在 FileReader 加载字符串后的回调代码:

function upload_to_album(binaryString, filetype, albumid) {

var method = 'POST';
var url = 'http://picasaweb.google.com/data/feed/api/user/default/albumid/' + albumid;
var request = gen_multipart('Title', 'Description', binaryString, filetype);
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.setRequestHeader("GData-Version", '3.0');
xhr.setRequestHeader("Content-Type", 'multipart/related; boundary="END_OF_PART"');
xhr.setRequestHeader("MIME-version", "1.0");
// Add OAuth Token
xhr.setRequestHeader("Authorization", oauth.getAuthorizationHeader(url, method, ''));
xhr.onreadystatechange = function(data) {
if (xhr.readyState == 4) {
// .. handle response
}
};
xhr.send(request);
}

gen_multipart 函数只是根据输入值和 XML 模板生成多部分,并产生完全相同的输出 as the specification (除了..二进制图像数据..),但为了完整起见,这里是:

function gen_multipart(title, description, image, mimetype) {
var multipart = ['Media multipart posting', " \n", '--END_OF_PART', "\n",
'Content-Type: application/atom+xml',"\n","\n",
"<entry xmlns='http://www.w3.org/2005/Atom'>", '<title>', title, '</title>',
'<summary>', description, '</summary>',
'<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#photo" />',
'</entry>', "\n", '--END_OF_PART', "\n",
'Content-Type:', mimetype, "\n\n",
image, "\n", '--END_OF_PART--'];
return multipart.join("");
}

问题是,POST 负载不同于原始图像数据,因此导致错误请求(Picasa 不会接受图像),尽管它在使用时工作正常

xhr.send(file) // With content-type set to file.type

我的问题是,如何获取真实二进制图像以将其包含在多部分中?我假设只是将它附加到 xml 字符串就被破坏了,但我似乎无法修复它。

请注意,由于 old bug in Picasa , base64 不是解决方案。

最佳答案

XMLHttpRequest specification声明使用 .send() 方法发送的数据被转换为 unicode,并编码为 UTF-8。

上传二进制数据的推荐方式是通过FormData应用程序接口(interface)。但是,由于您不只是上传文件,而是将二进制数据包装在 XML 中,因此此选项没有用。

解决方案可以在FormData for Web Workers Polyfill的源代码中找到,这是我遇到类似问题时写的。为了防止 Unicode 转换,所有数据都被添加到一个数组中,最后作为 ArrayBuffer 传输。 .传输时未触及字节序列,per specification .

下面的代码是一个特定的导数,基于FormData for Web Workers Polyfill :

function gen_multipart(title, description, image, mimetype) {
var multipart = [ "..." ].join(''); // See question for the source
var uint8array = new Uint8Array(multipart.length);
for (var i=0; i<multipart.length; i++) {
uint8array[i] = multipart.charCodeAt(i) & 0xff;
}
return uint8array.buffer; // <-- This is an ArrayBuffer object!
}

当您使用 .readAsArrayBuffer 时,脚本变得更加高效而不是 .readAsBinaryString :

function gen_multipart(title, description, image, mimetype) {
image = new Uint8Array(image); // Wrap in view to get data

var before = ['Media ... ', 'Content-Type:', mimetype, "\n\n"].join('');
var after = '\n--END_OF_PART--';
var size = before.length + image.byteLength + after.length;
var uint8array = new Uint8Array(size);
var i = 0;

// Append the string.
for (; i<before.length; i++) {
uint8array[i] = before.charCodeAt(i) & 0xff;
}

// Append the binary data.
for (var j=0; j<image.byteLength; i++, j++) {
uint8array[i] = image[j];
}

// Append the remaining string
for (var j=0; j<after.length; i++, j++) {
uint8array[i] = after.charCodeAt(j) & 0xff;
}
return uint8array.buffer; // <-- This is an ArrayBuffer object!
}

关于javascript - XMLHttpRequest:多部分/相关 POST,以 XML 和图像作为有效负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8262266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com