Использовать GM_xmlhttpRequest для отправки данных в Chrome?

Я пишу сценарий пользователя, чтобы взять изображение со страницы и загрузить его на сервер. Скрипт отлично работает в FF (Greasemonkey и Scriptish), но когда я использую Chrome (используя Tampermonkey или Ninjakit), он не отправляет данные, вместо этого он отправляет строку * [object Object] *.

Вот мой сценарий:

// ==UserScript==
// @id             myid
// @name           myname
// @version        1.0
// @namespace      ohadcn
// @author         Ohad Cohen
// @description    mydescription
// @include        https://*
// @grant          GM_xmlhttpRequest
// @require        https://code.jquery.com/jquery-2.0.3.min.js
// @run-at         document-end
// ==/UserScript==

function getBase64Image(img) {
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);
    var dataURL = canvas.toDataURL("image/png");
    return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}

img=$("img[alt=myImage]").get(0);

img.onload=function(){
    var img64=getBase64Image(img)
    var _data=new FormData();
    _data.append("image64",img64);

    GM_xmlhttpRequest({
    method: "POST",
    url: "http://myserver.org/mysscript.py",
    headers: {
    "Content-Type": "multipart/form-data"
    },
    data:_data,
    onload: function(response) {
             console.log ("gut response");
         $("#input").get()[0].value=response.responseText;
    }
    });
}


И Tampermonkey, и Ninjakit отправляют запрос. В Tampermonkey я получаю ответ, в Ninjakit - нет (onload никогда не вызывается).

Но они не отправляют фактическое изображение, закодированное с помощью base64 - когда я читаю данные - сервер получает [объект Object] в качестве тела POST (вместо тела данных я не могу заставить сетевую панель devtools показывать запросы, сделанные GM_xmlhttpRequest, поэтому я проверил это на стороне сервера).

2 ответа

Решение

Это может быть FormData а также multipart/form-data не очень хорошо поддерживаются на этих платформах. Нужно разобраться в этом подробнее (позже).

Тем временем, попробуйте более типичный подход; использование application/x-www-form-urlencoded или JSON.

НАПРИМЕР:

GM_xmlhttpRequest ( {
    method:     "POST",
    url:        "http://myserver.org/mysscript.py",
    data:       "image64=" + encodeURIComponent (img64),
    headers:    {
        "Content-Type": "application/x-www-form-urlencoded"
    },
    onload:     function (response) {
        console.log ("gut response");
        $("#input").get()[0].value=response.responseText;
    }
} );

Вы можете сделать это хотя бы в Tampermonkey , установивfetchпараметр дляtrue. Таким образом, когда вы передаете экземпляр параметра в качестве параметра, он просто работает. Не уверен, поддерживают ли другие менеджеры пользовательских сценариев использование выборки вместо XMLHttpRequest, но Greasemonkey поддерживаетFormDataвdataполе в любом случае.

          let fd = new FormData()
    fd.append('field_name', 'field_value')
    fd.append('file_upload', file) // an instance of File
    
    GM.xmlHttpRequest({
      method: "POST",
      url: "https://upload.api",
      onload: function(res) {
        // ...
      },
      onerror: function(e) {
        // ...
      },
      data: fd,
      fetch: true
    })
Другие вопросы по тегам