Использовать 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
})