действительно ли возможно отправить двоичный запрос XHR с помощью .send ()? - PullRequest
3 голосов
/ 26 апреля 2011

действительно ли возможно отправить двоичный 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 && 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 Ответ

0 голосов
/ 26 апреля 2011

У меня есть пара проблем, которые я вижу.

Во-первых, я не могу успешно установить заголовок Content-Length из скрипта. Когда я пытаюсь это сделать, я получаю сообщения об ошибках в Chrome. Похоже, что в этом нет необходимости, поскольку браузер устанавливает правильную длину содержимого для всех моих тестовых случаев.

Во-вторых, вы добавляете заголовок Content-Type и помещаете искусственный заголовок Content-Type в тело вашего запроса:

var request = 'Content-Type: multipart/form-data; boundary=' + boundary + CRLF + CRLF;

Эта строка должна быть удалена. Вы уже устанавливаете правильный заголовок. Вы не можете фактически установить заголовки в теле в любом случае. Вероятно, это источник вашей проблемы: эта строка делает ваше тело запроса недействительным, поэтому, конечно, сервер не может его проанализировать.

После некоторых экспериментов я разработал рабочий пример того, как это можно сделать. Я проверял это в последних версиях Chrome, Firefox 4, IE9 и IE6. Библиотеки не использовались, хотя, конечно, если они у вас есть, это значительно упростит код.

Пожалуйста, дайте мне знать, если вы обнаружите какие-либо проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...