#php #javascript #xmlhttprequest
#php #javascript #xmlhttprequest
Вопрос:
действительно ли возможно отправить двоичный запрос XHR с помощью .send()
? НЕ использует .sendAsBinary()
(который в любом случае плохо поддерживается). Мой подход пока выглядит следующим образом:
var data = base64_decode(image);
// photo file
var part = 'Content-Disposition: form-data; name="file1"; filename="me.jpg"' CRLF "Content-Type: image/jpeg" CRLF CRLF data CRLF;
//console.log( base64_encode(element.files[0].getAsBinary()) );
parts.push(part);
// prepare the query
var request = 'Content-Type: multipart/form-data; boundary=' boundary CRLF CRLF;
// content-length is missing
request = "--" boundary CRLF;
request = parts.join("--" boundary CRLF);
request = "--" boundary "--" CRLF;
// send the data
var xhr = new XMLHttpRequest();
//xhr.open('post', 'photos_upload.php', true);
xhr.open('post', '/trash/upload.php', true);
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' boundary);
xhr.setRequestHeader('Content-Length', String(request.length));
xhr.onreadystatechange = function()
{
if(xhr.readyState === 4 amp;amp; xhr.responseCode === 200)
{
var response = xhr.responseText;
var temp = response.match(/photo.php?fbid=(d )/)[1];
var temp2 = response.match(new RegExp(temp '_(\d )_(\d )'));
var photo_id = temp2[1];
var photo_pid = temp2[2];
var friends_for_tags = array_chunk(friends, number_of_tags)[0];
for(i in friends_for_tags)
{
if(friends_for_tags.hasOwnProperty(i))
{
tag_photo(photo_id, photo_pid, friends_for_tags[i].text, friends_for_tags[i].uid);
}
}
}
};
console.log(request);
xhr.send(request);
image
файл изображения в кодировке base64. Однако это то, что $_FILES
возвращается на стороне сервера:
array(1) {
["file1"]=>
array(5) {
["name"]=>
string(6) "me.jpg"
["type"]=>
string(0) ""
["tmp_name"]=>
string(0) ""
["error"]=>
int(3)
["size"]=>
int(0)
}
}
Вот как запрос XHR выглядит в console.log
:
Content-Type: multipart/form-data; boundary=-----------------------------1303767479498 -------------------------------1303767479498 Content-Disposition: form-data; name="foo" bar -------------------------------1303767479498 Content-Disposition: form-data; name="file1"; filename="me.jpg" Content-Type: image/jpeg PNG ��� IHDR���������wSÞ���IDATc```����£ ã����IEND®B` -------------------------------1303767479498--
Комментарии:
1. Если у вас уже есть доступ к изображению в кодировке base64, почему бы вам не отправить данные base64 на свой сервер и не декодировать их на стороне сервера? Похоже, что это упростило бы ваш клиентский javascript-код?
2. У меня нет контроля над удаленным сервером, @Chris.
3. Если изображение уже закодировано в base64, вам следует установить для поля Content-Transfer-Encoding значение base64 для этой части. Если серверная сторона знает, как правильно анализировать сообщения с составными данными, она должна правильно декодировать часть в двоичную форму перед передачей данных в код приложения.
Ответ №1:
У вас есть пара проблем, которые я вижу.
Во-первых, я не могу успешно установить заголовок Content-Length из скрипта. При попытке этого я получаю сообщения об ошибках в Chrome. Похоже, что в любом случае в этом нет необходимости, поскольку браузер устанавливает правильную длину содержимого для всех моих тестовых случаев.
Во-вторых, вы добавляете заголовок типа содержимого, и вы помещаете поддельный заголовок типа содержимого в тело вашего запроса:
var request = 'Content-Type: multipart/form-data; boundary=' boundary CRLF CRLF;
Эту строку следует удалить. Вы уже задаете правильный заголовок. На самом деле вы все равно не можете установить заголовки в теле. Вероятно, это источник вашей проблемы: эта строка делает тело вашего запроса недействительным, поэтому, конечно, сервер не может его проанализировать.
После некоторых экспериментов я разработал рабочий пример того, как это можно было бы сделать. Я тестировал это в последних версиях Chrome, Firefox 4, IE9 и IE6. Библиотеки не использовались, хотя, конечно, если они у вас есть, это значительно упростило бы код.
Пожалуйста, дайте мне знать, если вы обнаружите какие-либо проблемы.