$_REQUEST and $_FILES not populating on multipart/form-data - javascript

I have an ajax call bring up a form, this ajax call is successful using a string of variable var=value&var2=value2 etc. So i know that the AJAX Response is working.
Once the form is loaded into the AJAX Response it is parsed for any Javascript that needs to be run. I have an applet that I am building that modifies the form to upload four images.
$inRetailImages = "<script>ImgShower.init()</script>";
$inRetailImages .= "<div id=\"retailimagescontainer\"></div>";
This parse fine and loads the Javascript applet which is then used to load four images into it. When loading the four images, it modifies the form with an input for each image. I see this happening in the browsers debugger.
input = document.createElement('input');
input.id= "addShowerImage" + id;
input.name= 'addShowerImage' + id;
input.type='file';
input.size='40';
input.runat = 'server';
input.style.display = 'none';
input.accept='image/jpeg';
input.onchange = function(){ ImgShower.select(id); }
formparent.appendChild(input);
This appends the input to the current form. This is working, because when i submit the form without the images using a string rather than a form object, the form recognises the inputs although they are not valid images, when submitting the AJAX call via a string of vars, it takes the value of the local file directory, which is obviously not what is needed, but shows the AJAX call is working and the process script for the PHP is working. This form works perfectly when not uploading images.
if(isString(params)){
params = params + '&mode=' + mode;
contenttype = 'application/x-www-form-urlencoded';
}
else if (isObject(params)){
params.mode = mode;
queryparams = Request.getQueryParamsAsObject(params.params);
Objects.merge(params, queryparams);
delete params["params"];
var formParams = new FormData();
for (key in params) {
formParams.append(key, params[key]);
log("error", "FormData Key: " + key + " Data:" + params[key]);
}
params = formParams;
//contenttype = "multipart/form-data;Charset=UTF-8;boundary=xxxxx;";
//contenttype = 'application/x-www-form-urlencoded';
EDIT: I CHANGED THE CONTENT TYPE TO FALSE
contenttype = false;
AND PUT AN IF STATEMENT TO PUT NO HEADER IN THE AJAX SEND
AND EDITED
formParams.append(key, params[key] || "");
SO THAT THE PASSED VALUES WERE NOT EMPTY AND THE FORM SENDS
IT STILL WONT PASS AN IMAGE FILE TO $_FILES BUT THIS MADE IT FILL $_REQUEST
}
I have a script that takes all the value from the form and turns it into an Object Array. In the debugger i can see all the values from the form as expected including the FileItem for each of the four images. When view the log from the script above loading it into the formData object, i can see the valid entries and they all look good.
I have tried multiple content types, i have tried sending just the object without the form data, i have tried adding a new form wrapper to the form data, i have tried naming a new form wrapper for the formData object, i have looked through my PHP settings, and gone through this list.
Why would $_FILES be empty when uploading files to PHP?
The list of to watch out for is pretty extensive and my php.ini settings seem fine.
When i submit the form using application/x-www-form-urlencoded i see a large multipart in the response, but it does not populate $_REQUEST, $_POST or $_FILES as one would excpect. It loads the $_REQUEST with one variable and the multipart data.
When i submit the form using multipart/form-data, i see the Response in Googles Network Tab as a Payload being sent to the PHP Server, but at the PHP end it does not populate $_REQUEST, $_POST or $_FILES at all.
This is what i see in the Payload of the Request and Response on Google Chromes Network Tab of the Developer Tools.
------WebKitFormBoundaryp39DDe2JV8jjxA5j
Content-Disposition: form-data; name="addRetailName"
asdasd
------WebKitFormBoundaryp39DDe2JV8jjxA5j
Content-Disposition: form-data; name="addRetailCode"
TEST001
------WebKitFormBoundaryp39DDe2JV8jjxA5j
Content-Disposition: form-data; name="addRetailManuf"
etc for 34 fields
This form has 34 fields, + the 4 added fields using the javascript to update the form. These images can be seen in the Payload as well.
------WebKitFormBoundaryzmu5mDvaLNnvsolE
Content-Disposition: form-data; name="addShowerImage1"
[object FileList]
Why does this not populate the $_REQUEST and $_FILES arrays. I output the arrays in the PHP using print_r($_REQUEST) or print_r($_FILES) and get array() as the response.
I am not getting any files coming through, nor am i getting any form data coming through at all. Yet i see the multipart being sent in the Payload of the Request.
I am using pure javascript with no libraries and no jscript. I prefer to write in pure javascript.
I should also state, that i am on a windows 7 ultimate machine using IIS 7 and PHP 5.4. via FastCGI.
When calling the ajax, the form is passed and collected by a request function. This function scrolls through all the items of the form and collects their values or contents. This works for all text based content.
I call all file inputs
var inputs = formObj.getElementsByTagName("input");
then traverse through those inputs
case "file":
values[input_name] = inputs[i].files;
break;
return values;
I even tried
values[input_name] = inputs[i].files[0]; returns File and not FileList
and i get this in the Payload
------WebKitFormBoundaryqsinSx1UoPEKAYOD
Content-Disposition: form-data; name="addShowerImage1";
filename="13006682_10208925038300663_5601989752145619827_n.jpg"
Content-Type: image/jpeg
This is then an Object Array
values{var1: value1, filevar: File}
It seems the FileList/File is appearing here. This is at the very beginning of recieving the form submit, the function traversing all the form values sees the files>fileList. I dont see anything other than fileList.

Related

Not getting file data in Extjs Ajax request

I have a form on form-window, and inside form window I have a form with many fields and one upload button. When try to submit form using Ajax.request I have got textfield value but can not get file data. Except filename.
var fd = Ext.getCmp('users-form').form;
var fileInput = document.getElementById('company_logo');
console.log(fd.getEl().dom.files);
params = {
name : fd.findField('name').getValue(),
login : fd.findField('login').getValue(),
email : fd.findField('email').getValue(),
password : fd.findField('password').getValue(),
password_repeat : fd.findField('password_repeat').getValue(),
id : fd.findField('id').getValue()
company_logo : fd.findField('logo').getValue()
}
console.log(params);
Ext.Ajax.request({
url: Scada.reqUrl('users', 'save'),
method: 'post',
params: {
data: Ext.encode(params)
},
success: function() {
console.log('in success');
},
failure: function() {
console.log('in failure');
}
});
Here logo is input type file. I want to send logo data with ajax request. Please help me to figure out the problem. Thanks
Not sure why you started a new question instead of editing Encode form data while fileupload true in Extjs Form Submit as this seems to be the same problem.
Assuming logo is your file upload field you are trying to get the file data using getValue does not actually return the file content (if you use modern there is a getFiles method which returns the selected file objects).
General problems with your approach:
As I stated in my original answer it is not a good idea to send files in a standard ajax request. In your case those problems are:
If you expect getValue to return file contents, you are potentially encoding binary data into a JSON string. This will maybe work but create a large overhead and as the only available JSON datatype that could handle this content is string your parser would have to guess that property company_logo contains binary data and needs to be somehow converted into some sort of file reference.
You are sending files without metadata, so when just adding the raw content into your JSON string you would not be able to detect the expected file type without testing the file in multiple ways
As far as I know you would not be able to access the file content in classic toolkit at all
Submitting the data as a form: In your original question you explained that you submit the form instead of doing Ajax requests which is generally the preferred way.
When you submit a form that contains a file upload field the form will automatically be submitted as multipart/form-data the raw files are added to the request body with it's original content while preserving metadata collected by the browser.
If you look at https://docs.sencha.com/extjs/7.0.0/modern/Ext.Ajax.html#method-request you would have to set isUpload to true and use the form proeprty instead of params, passing a reference to the parent form.

Saving Javascript FormData() Object on client side

I have a html page which contains a form element with some text and file input elements.
This from is submitted with an ajax call to the server using a method suggested here: How can I upload files asynchronously?
As you may see in the referenced page from the above link, the FormData() object is used as a container for inputed data and I have done the job successfully.
But now we want to create a new page that have these html elements, save the text and file inputs on client side (Cookie or Local Strorage or . . .) and do the ajax submit later on another page.
I wasn`t able to save new FormData() in either cookie or local storage; what got saved is a small string:"[object FormData]" instead of entered file and strings.
I also tried using JSON.stringify() with no success; it just returned an empty JSON("{}").
(the code is using jQuery selector)
var postData = new FormData($(form)[0]);
// var sPostedData = JSON.stringify(postData); // returns: "{}"
var myStorage = window.localStorage; // returns: "[object FormData]"
myStorage.setItem("contentOrder", postData);
Please help, how should I save this object on my client-side?
To get the file from form data use formData.get('file') where file is the name of an input. The returned object will be of type Blob (see how to get its content).
The complete example can be found in this fiddle: https://jsfiddle.net/skm5m467/1/

form.submit() truncating string with '?'

I have a JavaScript function :
function post(aAction) {
var form = document.createElement("form");
form.action=aAction;
document.body.appendChild(form);
form.submit();
alert(form.action);
}
( I'm an experienced developer but not much experience with JScript - lifted that post() function from some website. )
I am passing this string into the function: A URL with query information:
http://testServer:3072/aQuerySite.dll/GetErrors?server=server1:5678
This URL returns a page listing error messages from the specified server: "server1:5678" - an argument passed to a server side query as
server=server1:5678
in the URL.
If I paste that URL directly into a browser and post it, the correct page with appropriate data is returned, and the browser address shows the complete URL as it was sent.
But when I pass the URL into my function, I get back a correctly formatted page but no records, and the browser address shows the URL truncated after the ? token : http://testServer:3072/aQuerySite.dll/GetErrors? The page returns showing no records because the query parameters after ? never got to the server for evaluation - query runs looking for nothing.
alert(form.action) in the function, which I added for debugging, shows the correct URL with query arguments, as does my debugger (WebStorm) and as mentioned, if I hit the URL directly from the browser, I get the correct result. I can only conclude that my URL is getting truncated in the form.submit() call.
This happens in IE, FireFox and Chrome. I also tried using ? for "?" - same result.
Why is this happening? How can I fix it?
It seems like you're trying to use a newly created form to redirect a user through its submission.
That is not necessary, as you can simply redirect the user using the following:
window.location = 'your_url';
In your case, you say that the querystring is being replaced with a simple ?.
That's because you created a form, and this form uses GET to post its data.
So if the form action is https://www.stackoverflow.com, the query string will be added with a interrogation following by the key/value pairs.
Let's suppose you have a form with two inputs named a and b, when you submit them, the query string would look like this:
https://www.stackoverflow.com?a=zzz&b=zzz
If you simply put this url in your form action, it will replace the query string with its own data when you submit it. Since your form has no named inputs, the query string will be empty, that's why you have an empty ? after the url.

Passing JSON to the server like GET/POST to get a file instead of ajax reply

I've an object created in javacript with a lot of data and I serialize it to JSON to send it to the server. After this, the server must do somework and create a dynamic file, so it can be downloaded.
For the last routine I created an ASHX but can be modified. Already I'm getting a "httpcontext" that I found in another question how to work with it to get the data from the JSON, so my question is not related about this.
The problem (more oriented to JS) is this one:
How can I sent the JSON to the ASHX as a URL/GET/POST to the generic handler to avoid the "ajax reply" and be the user open a new window with the link dinamically generated?
Thanks, sorry for my english (please edit) and kind regards!
Note 1: I can't use third-part code
Note 2: I can't use JSON.NET
Note 3: I can't save the report on the server so the response must be a generated file to download, even more, the download itself is the response of the server.
---UPDATE----
I've been read this question:
Can I post JSON without using AJAX?
The only thing I don't understand from that question is how to make it work, thinking in that I've a "link" to download
I assume you do not want to refresh the whole page so there is a workaround.
1) Ajax-load an iframe which is a separate aspx file for example.
2) In the codebehind of that separate aspx file, generate the file in memory and convert it to an array of bytes.
3) Then use Response to stream the bytes to the user.
Finally I resolved the issue with this (in the right way).
I just take my json object and send it trough POST with a dynamic form generated with javfascript
var dataToPostInExport = JSON.stringify(queryToVerify);
//Convert To POST and send
var VerifyForm = document.createElement("form");
VerifyForm.target = "_blank";
VerifyForm.method = "POST";
VerifyForm.action = "file.ashx";
var dataInput = document.createElement("input");
dataInput.type = "hidden";
dataInput.name = "mydata";
dataInput.value = dataToPostInExport;
VerifyForm.appendChild(dataInput);
document.body.appendChild(VerifyForm);
VerifyForm.submit();
Then in the ashx file:
Dim DataToParse As String
DataToParse = HttpContext.Current.Request.Form("mydata")
Dim JSSerializer As New JavaScriptSerializer
Dim QueryToExport as my very own type!
QueryToExport = JSSerializer.Deserialize(Of My Own Type)(dataToParse)

Sending big data to server, Cross-Domain

I'm trying to send chunks of data from many different servers my app is on, to mine.
Using some dummy image source, passing my data as a GET query. (img.gif?aaa=xxx&bb=yyy...)
the Query is many times too long and gets cut.
is there some better way for me to send the data cross-browser?
It would be the best if you used POST method when sending the data.
var msgSender = new ActiveXObject("Microsoft.XMLHTTP");
msgSender.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
msgSender.setRequestHeader("Encoding", "Windows-1257")
msgSender.open("POST", "http://yourderver/page" ,true);
msgSender.onreadystatechange = function(){...};
var msg = "your very long message goes here";
//preparing post data
var strToSend = "someotherarg=somevalue" + username;
strToSend+= "&msg=" + msg;
strToSend = escape(strToSend);
msgSender.send(strToSend);
The solution is even easier, if you use jQuery - just call $.post() method: http://docs.jquery.com/Ajax/jQuery.post
EDIT:
However, this will not work cross-domain, unless you specify 'Access-Control' headers on your server and the clients have modern enouhg browsers (FireFox 3.5+ etc)
So, another solution is to include a hidden IFRAME in your page (the page lives on your server then) which contains a form and you call Submit() of that form to POST the data.
Split your payload (e.g. at 1024 bytes), then send using several GET requests.

Categories