How to pass formData to postData in loadOneTab? - javascript

I have a formData object and would like to pass it to loadOneTab()
Example:
var formData = Components.classes['#mozilla.org/files/formdata;1']
.createInstance(Components.interfaces.nsIDOMFormData);
formData.append('Content-Type', 'multipart/form-data');
formData.append('filename', '');
formData.append('image_url', URL);
How can I pass above object to postData
window.gBrowser.loadOneTab('https://www.example.com/',
{inBackground: false, postData: postStream});

I already kinda answered this as part of your last question.
Unfortunately we cannot use FormData here, as there is currently no way to get the stream (and other information) from a FormData instance (nsIXHRSendable is not scriptable, unfortunately). postData however expects the value to be an nsIInputStream instance.
So there is no way to use FormData in conjunction with loadOneTab and friends (essentially all <tabbrowser> and <browser> methods expect a stream if they accept a postData argument).

Related

Creating a file from a blob

I'm in need of some javascript guru. I have this code:
handleImage(new File([blob], blob.name, {type: blob.type})).done(/* something */)
and
handleImage = function (image) {
// create some fake form data
var formData = new FormData();
formData.append("attachment", image);
formData.append("auto", true);
formData.append("_csrf", "xxxxxxxxx");
// post to the server.
return $.ajax({
url: "/some/url",
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
error: function () {
console.log("error");
}
});
This works fine with Chrome and Firefox, but when using Safari (10.1.1), the server (java / spring mvc) receive in the MultipartHttpServletRequest an empty file for "attachment". So it seems to me that new File([blob], blob.name, {type: blob.type}) is somehow failing.
Any idea of what's wrong here?
This is probably a bug in safari's young implementation.
But why do you even convert it to a File object ?
A File object is a Blob, the only difference being that it has a name and a lastModified properties. But since you already seem to extend your blob, it leaves only this lastModifiedproperty that you could add too anyway.
The only API I can think of, where it makes a difference if your object is a Blob or a File is FormData.append method ; where if you pass a File object, it will be able to set the filename automatically. But this method has a third parameter, allowing you to set this filename.
So if you change your code to include formData.append("attachment", image, image.name); and call it with handleImage(blob) directly, it will do exactly the same request as the one you're doing, except that it will work on Safari and every other browser that don't support the File constructor (looking at you IE).

Response data is not in valid format in Ajax

I have a text file with the character set as "Shift_JIS" and the file contains Japanese characters. And then I do ajax request to that file as shown below.
$.ajax({
url: "demo.txt",
success: function(result){
alert(result);
}}
);
But the data that is shown in alert is not valid Japanese character. Instead it shows some junk data. Even though I tried to set the response header character set and I do many of the solution that is already before in stackoverflow, But it didn't work. Can any one help me to solve this ?
Note: Browser is Internet Explorer
You said you tried to change the charset, have you tried changing the contentType to plain text ? :
$.ajax({
/*...*/
contentType: "text/plain; charset=Shift_JIS"
/*...*/
})
You cannot read a Shift_JIS file into a string object directly in JavaScript. You have to once store the content of the file into a binary object and then decode it into UTF-16 (the internal representation of JavaScript string) with TextDecoder.
Unfortunately, jQuery's $.ajax() cannot handle the response body as binary (dataType: 'binary') out of the box. So you have to use additional module like
jQuery BinaryTransport, or use XMLHttpRequest like this:
// ref. https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
var oReq = new XMLHttpRequest();
oReq.open("GET", "demo.txt", true);
oReq.responseType = "arraybuffer"; // handle response body as binary
oReq.onload = function (oEvent) {
if (oReq.response) {
var sjisDecoder = new TextDecoder('shift-jis');
alert(sjisDecoder.decode(oReq.response)) // Note: not oReq.responseText
}
};
oReq.send(null);

Use FormData after passing it to a new function

I'm not sure if this question is worth asking but I can't seem to find a workaround so here I am.
I have a Flask app in which I submit a form that uploads an image to the server. I send the image using FormData that is created this way:
$( "#myform" ).submit(function(event) {
event.preventDefault();
var $form = $(this),
formObject = $('form')[0],
formData = new FormData(formObject);
// other stuff
The FormData is then sent via an AJAX POST request to the sever. This operation works perfectly when the POST request is inside the submit function.
The problem is that in an other view, I need to use the same code but I moved the AJAX POST requests out of the submit function. So when I pass either my formObject or formData to the function that contains the AJAX requests, let's call it fctA, they are undefined.
I think I see the problem, since the submit function has a "particular status" (as you can use $(this) to get the form) but I can't find a way to pass the formData to an other function. I don't want to get rid of fctA since it saves me from duplicating a lot of code (because of client-side verifications)
Is there a way to pass FormData through different function calls?
Thanks in advance.
//Edit: Here's the code where I want to pass the FormData
//(I'm having trouble indenting it here)
$.ajax({
url: "url",
type: "GET",
dataType: "json",
success: function(data) {
//Create a JSON object to send other form inputs
/*
fctA is used to avoid duplicating AJAX POST requests since I
need to send the data only when meeting some expectations and
I must display error messages otherwise.
*/
fctA(json, formObject)
/*
The image is correctly sent if I have a POST request that
uses formData right here instead of passing it to fctA.
As soon as the POST request leaves the submit function to go to fctA though,
formData is undefined when I execute the code.
I tried passing formObject or formData, they are both undefined.
*/
},
error: function() {
//Display an error message
}
});
I am not sure why exactly it does not work, but it is probably caused by your variable scopes. formObject and formData are global variables because you don't declare them with var. fctA is called by the ajax-success-handler in case of a successful ajax-request. formObject is passed to fctA. Where does formObject come from? One might expect that it is available in the global scope. This seems not to be true for some reason.
I recommend to declare variables locally using var and I guess most people will agree. Global variables allow influences between arbitrary pieces of code that are hard to overlook, hard to govern and in effect hard to maintain. Global variables also increase the risk of accidently giving two variables the same name that are meant be distinct variables.
If you declare your variables locally then you can wrap your call to $.ajax in a function with formObject as parameter and call this function in the submit-handler. formObject will also be available in the ajax-success-handler because Javascript supports closures. So, if you use variable scopes the recommended way there is a good chance that you won't have the problem any more.
Alright I found the solution, the problem was that I passed my formData to a function which had a keyword argument as last parameter so the formData was the value of the keyword argument (since the default value was used in that call) and of course, the argument where I expected my formData to be was undefined.
Should I delete the whole question since it's almost no more than a typo problem? The warning that tells you your account may be blocked if you delete too many questions kinds of puts me off.

FormData is not a constructor

I'm trying to make a ajax request to upload a image. My problem is when I create the FormData. My console is saying "dataForm is not a constructor".
How can I solve this ?
here is my script
$("#new-broadcast-image-static").on("change", function(formData) {
var formData = new formData();
// line that console point the error //
var file = $("#new-broadcast-image-static")[0].files[0];
formData.set("image", file);
$.ajax({
url: apiUrl + "image/upload",
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
xhrFields: {
withCredentials: true
},
success: function(data) {
hashNewBroadcastImage = data.data.identifier;
$("#hash-new-broadcast-image-static").val(hashNewBroadcastImage);
}
});
});
Capitalize it: var formData = new FormData();
But what are you trying to acomplish anyways? You are reasigning a variable you are getting as parameter:
$("#new-broadcast-image-static").on("change", function(formData) {
var formData = new formData();
You probably want to change it to something like
$("#new-broadcast-image-static").on("change", function(e) {
var formData = new FormData();
Not totally sure about it, but I think you have a capital letter mistake, you've write formData() instead of FormData()
The correct way:
var formData = new FormData();
Please Check this Possibility it will definitely solve your problem
Anywhere in your JS Code if you are assigning a value to FormData like below
FormData={"PersonID":1,"PersonName":"Test"};
and if you use like this
var a = new FormData();
Then it will throw an error like "FormData is not a constructor as it is already declared as an Object".
as my experience sometime because of in javascript function is debugger mode.
I tried all of the solutions for this and none worked. After hours of pulling my hair out, I discovered it was because I had a filed named FormData, which was a partial Vue Pinia State. I changed the name of that file to formData and it worked. So if you run into this problem and can't solve it and you have FormData used as a variable or file name anywhere in your project - change it and see if that fixes it.

Sending XMLHttpRequest with FormData

I am trying to make an XHR with JavaScript, but I can't get it to work correctly.
When I see the right requests in the "Network" tab of the Chrome developer tools I see that they have a "Form Data" section where are listed all the informations sent with the request, like this:
Now, I've tried making my XMLHttpRequest in any way I know, but I can't get that result.
I have tried this:
var xhr = new XMLHttpRequest(),
form_data = "data%5Btumblelog%5D=drunknight&data%5Bsource%5D=FOLLOW_SOURCE_REBLOG";
// this is uri encoded: %5b = [ and %5D = ]
xhr.open('POST','https://www.somesite.com/page?' + form_data, false);
xhr.send();
But I got this "Query String Parameters" instead of "Form Data":
I have also tried this:
var xhr = new XMLHttpRequest(),
formData = new FormData();
formData.append("data[tumblelog]", "drunknight");
formData.append("data[source]", "FOLLOW_SOURCE_REBLOG");
xhr.open('POST','https://www.somesite.com/page', false);
xhr.send(formData);
But I got this "Request Payload" instead of "Form Data":
And, finally, I have tried this:
var xhr = new XMLHttpRequest(),
formData = {
"data[tumblelog]": "drunknight",
"data[source]": "FOLLOW_SOURCE_REBLOG"
};
xhr.open('POST','https://www.somesite.com/page', false);
xhr.send(JSON.stringify(formData));
But I got another "Request Payload" instead of "Form Data":
Now, my question is: how can I send my XMLHttpRequest in order to obtain the same result as shown in the FIRST image?
You're missing the Content-Type header to specify that your data is form-like encoded.
This will work:
var xhr = new XMLHttpRequest(),
data = "data%5Btumblelog%5D=drunknight&data%5Bsource%5D=FOLLOW_SOURCE_REBLOG";
xhr.open('POST','https://www.somesite.com/page', false);
// LINE ADDED
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);
EDIT
FormData is generally used to send binary data and will automatically set the Content-Type header to multipart/form-data (see FormData Spec and FormData Examples). However you have to make sure the server also accepts request using this MIME-type, which apparently is not your case, as you already tried and it didn't work.
I noticed the OP tried using FormData in one of their iterations to solve the original problem.
I've recently started using the Fetch api for sending form data. It's designed with promises making it really easy to use (especially if there's a form to leverage for all of the inputs):
var form = document.forms[0];
var data = new FormData(form);
fetch(form.action, { method: form.method, body: data })
.then((response) => {
// handle response
}).catch((error) => {
// handle error
);
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Posting this as an answer because I believe it will give you exactly what you want to know;
I just want to know what sort of method is used to send that kind of data. I can assure you that the first image is obtained using an XHR
You haven't given enough information for us to see how the "correct" version is generated, but you can capture the relevant bits you want, drop in code like this before the working XMLHttpRequest is .opened;
(function (obj, methods) {
var i;
function log() {
console.log.apply(console, arguments);
}
for (i = 0; i < methods.length; ++i)
obj[methods[i]] = (function (method_name, method) {
return function () {
log.call(null, method_name, arguments);
return method.apply(this, arguments);
}
}(methods[i], obj[methods[i]]));
}(XMLHttpRequest.prototype, ['open', 'send', 'setRequestHeader']));
Now perform the action to make it fire and the relevant parameters will be logged so you can see exactly what happens to it as it is set up and sent, which should allow you to know what to pass into your one.
The problem is that I get a forbidden (403)
I'm going to assume this is not a same origin security-error because this looks server-returned and not a browser-initiated abort

Categories

Resources