Reputation: 6144
I'm writing a user script to take an image from a page, and upload it to a server. The script works fine in FF (Greasemonkey and Scriptish), but when I use Chrome (using Tampermonkey or Ninjakit), it does not send the data, it sends the string * [object Object] * instead.
Here is my script:
// ==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;
}
});
}
Both Tampermonkey and Ninjakit do send the request. In Tampermonkey, I get a response, in Ninjakit I don't (onload is never called).
But they do not send the actual image encoded with base64 - when I read the data - the server gets [object Object] as the POST body (Instead of data body, I can't get devtools network panel to show requests made by GM_xmlhttpRequest, so I checked it on the server side).
Upvotes: 6
Views: 22075
Reputation: 740
You can do it at least in Tampermonkey by setting the fetch
parameter to true
. This way when you pass an instance of FormData
as data
parameter it will just work. Not sure if other userscript managers support using fetch instead of XMLHttpRequest but Greasemonkey supports FormData
in the data
field anyways.
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
})
Upvotes: 0
Reputation: 93473
It might be that FormData
and multipart/form-data
are not well supported on those platforms. Need to look into it more (later).
Meanwhile, try the more typical approach; use application/x-www-form-urlencoded
or JSON.
EG:
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;
}
} );
Upvotes: 7