How to set boundary while using XmlHttpRequest and FormData - javascript

I am trying to set the boundary correctly in the header while using FormData to post the XmlHttpRequest:
xhr.open("POST",url);
xhr.setRequestHeader("Content-type","multipart/form-data; boundary=...");
var formData = new FormData();
formData.append("filename", inputId.files[0]);
formData.append(...);
xhr.send(formData);
How do I get the boundary to be set in the request header here. I saw the request being set, the boundary is somehow created in the request. But the server has no idea on how to interpret it.

ES method
Simply don't set the Content-Type header manually and the browser will automatically set "multipart/form-data; boundary=..." value.
jQuery method
If you're using jQuery, set contentType option to false:
$.ajax({
url: url,
type: 'POST',
data: formData,
processData: false,
contentType: false
});

Try looking at this, How to send multipart/form-data form content by ajax (no jquery)? I am trying to work with this script with PHP as the reciever, having some problems with mixed results of warnings and I think my problem is that I have hacked away at the scripts both ends too much that its no longer functioning.
As for the comment by the other poster "If you're using JQuery", the only thing I have to say to that comment is that it is not helpful to the person not working in JQuery and JQ is not the be all and end all of scripts.

Related

JQuery AJAX - Sending a JSONP form with attached files

I'm working in a contact form for our clients that creates webpages with us with their own domain. We offer them a hosting and a web editor to create their websites. When they create a contact form in their websites, whoever that visit their websites and fills a form to contact them, it is sent to our platform and it sends a email to our client notifying him/her that someone filled his/her contact form.
To make it work, we are using a jsonp ajax call in our clients webpage to send the form to our platform, which performs the email template and sends the email.
The problem now is that our clients asked to add a input field type to allow whoever that visits their page to attach a file to the form, so they can see an attached file in the contact notification email, but I can't find a way to do it using jsonp because it uses GET method to create a crossdomain request and everthing I've serarched in Stackoverflow, talks about using a POST method to send files with a form and get form data as new FormData().
Here is the code I had before trying the implementation:
var $form = $('form');
$form.submit(function(e){
e.preventDefault();
$.ajax({
url: url,
dataType: "jsonp",
data: $form.serialize(),
beforeSend: function () {
$form.data('allowSending', false); // To prevent multiple sendings while processing
},
success: function(data) {
alert(data.message);
$form.data('allowSending', true);
}
});
});
This is the code that I've tried, but it's not handled as expected:
var $form = $('form');
$form.submit(function(e){
e.preventDefault();
$.ajax({
url: url,
processData: false,
contentType: false,
dataType: "jsonp",
data: new FormData(this),
beforeSend: function () {
$form.data('allowSending', false); // To prevent multiple sendings while processing
},
success: function(data) {
alert(data.message);
$form.data('allowSending', true);
}
});
});
When it sends the filled form with the code that I've tried (the second one), tries to send the data as an object through the URL, like: ?callback=jQuery111107622947758095266_1459251318335&[object%20FormData]&_=1459251318336
How can I solve this?
Thanks in advance.
Regards.
PS: To make things harder, forms are completely dynamic, so if a solution is passing parameters manually, etc. it must be in a dynamic way with a for loop.
The short answer is that you can't.
Your attempt is failing because, since JSONP makes a GET request, contentType is ignored and data is treated as a string (since you said processData: false).
As you say, JSONP works by encoding everything in the URL. While it is possible to use the File API to read the content of the file and convert it into a base64 encoded string, that will exceed URL length limits for all but the smallest of files which makes it impractical.
Stop using JSONP. It is a, frankly dirty, hack that was used to sneak around the Same Origin Policy. We now have CORS, which is a standard, non-hacky, highly flexible method to selectively disable the same origin policy. One of the advantages of its flexibility is that you can make cross-origin POST requests using it.

W3C Validator offline on localhost by ajax

I use to programming Brackets text editor and I have already installed W3C validator but it working while I'm online but offine not. I try install https://validator.w3.org/docs/install.html and I running to localhost:8888 but brackets's extension connecting only via ajax (javascript). Is possible send ajax like to original W3C website?
Maintainer of the W3C HTML checker (validator) here. Yes it is possible to send an ajax request to a local instance of the current checker. To use Fetch to do it and get JSON-formatted results back:
var checkerUrl = "http://localhost:8888/?out=json"
fetch(document.location.href)
.then(function(currentDoc) { return currentDoc.text(); })
.then(function(htmlSource) {
fetch(
checkerUrl, {
method: "POST",
mode: "cors",
body: htmlSource,
headers: new Headers({ "Content-Type": "text/html;charset=utf-8" })
})
.then(function(checkerResponse) { return checkerResponse.json(); })
.then(function(jsonOutput) {
console.dir(jsonOutput.messages);
})
});
That shows the basic steps to follow to deliver the request in the way the checker expects:
send a document to the checker as the body of a POST (in this example, the current doc)
tell the checker to format its results as JSON (out=json)
make text/html;charset=utf-8 the media type of the POST body you send to the checker
The checker also supports multipart/form-data for giving it the HTML source to be checked, but giving it the source as a POST body instead is the preferred (and better) way for doing it.
If instead of using fetch() you want to use JQuery $.ajax(…), here’s an example:
var checkerUrl = "http://localhost:8888/?out=json"
$.get(document.location.href,
function(htmlSource)
{
$.ajax({
url: checkerUrl,
type: "POST",
crossDomain: true,
data: htmlSource,
contentType: "text/html;charset=utf-8",
dataType: "json",
success: function (jsonOutput) {
console.dir(jsonOutput.messages);
}
});
});
And if instead of either fetch() or JQuery $.ajax(…) you want to use old-school XHR but it’s not clear how to handle the details in that case, let me know and I can post an example of that too.
In all cases, the .messages JSON output is an array of objects that each contain something like:
firstColumn: 1
lastColumn: 6
lastLine: 4
message: "Unclosed element “span”."
type: "error"
The documentation for the checker JSON format gives more details of the JSON the checker emits.

Input::all() empty after FormData object passed

I have a form that I need to process before it's submitted. The form has several text and radio inputs, as well as a file one. I'm using jQuery to pass the form data:
$button.on('click', function(e) {
e.preventDefault();
var formData = new FormData($('.js-my-form')[0]);
$.ajax({
type: 'GET',
url: '/get-data',
data: formData,
contentType: false,
processData: false
}).done(function(response) {
// handle response
});
});
Then, in Laravel controller:
$input = Input::all() // <- EMPTY ARRAY
No idea why Input comes empty. Any help appreciated.
Your problem is that you are using a GET to send a request with enctype = multipart/form-data. When you use a native FormData object this is the format that you get by default. You can read how to send the form's data
using the POST method and setting the enctype attribute to application/x-www-form-urlencoded (default);
using the POST method and setting the enctype attribute to text/plain;
using the POST method and setting the enctype attribute to multipart/form-data;
using the GET method (in this case the enctype attribute will be ignored).
So if you set your requesto to a GET the content of your form present in the body of the request will be ignored. The enctype attribute is what tells the server how to process your request. This is why you should use POST.
Note that when you write
contentType: false,
processData: false
you are telling jQuery that do not mess with the data you are passing and leave your native Formdata object untouched. This will cause the enctype to be set automatically.
First i suggest use a type 'POST' to pass your data at your method and second, try serialize the form data
$.ajax({
type: 'POST',
url: '/get-data', /*Route laravel*/
data: formData.serialize(),
contentType: false,
processData: false
}).done(function(response) {
// handle response
});
So, I could not find any resource to confirm this, but it seems FormData won't work with GET type - at least when using jQuery's $.ajax() function.
Changed GET to POST - and the form input is getting to the Laravel controller with no problems.
Not sure I like it, thought, as I'm actually not POSTing anything, but GETting information I need. Anyways, it works.

jQuery POST to webservice via CORS

I have read a lot of topics about CORS & Javascript and about changing the headers in your post but I can't find the right example I am looking for.
So I'm going to first up start with explaining the situation:
I can not change anything to the webserver since this is out of my reach (It's a SAP Cloud Portal)
I can only change the POST code, so I can only control what I send.
The problem I have is described in the following Post:
jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox
--> My FF & Chrome Headers send a METHOD OPTIONS instead of METHOD POST.
I have written example code that works in IE but not in FF & Chrome:
var dataString = "<result><firstname>example</firstname><lastname>ThisIsSparta</lastname></result>";
var urlString = "http://delyo001.you.local:8000/sap/bc/youconsulting/ws/rest/anonymous/z_names_post";
//Add TO SAP.
var aData =
jQuery.ajax({
type: "POST",
contentType: "application/xml",
url: urlString, // for different servers cross-domain restrictions need to be handled
data: dataString,
dataType: "text",
success: function(xml) { // callback called when data is received
//oModel.setData(data); // fill the received data into the JSONModel
alert("success to post");
},
error: function(xml) { // callback called when data is received
//oModel.setData(data); // fill the received data into the JSONModel
alert("fail to post");
}
});
});
Or
var invocation = new XMLHttpRequest();
var url = 'http://delyo001.you.local:8000/sap/bc/youconsulting/ws/rest/anonymous/z_names_post';
var body = '<result><firstname>perthyrtyrtygop</firstname><lastname>sparta</lastname></result>';
invocation.open('POST', url, true);
invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
invocation.setRequestHeader('Content-Type', 'application/xml');
invocation.send(body);
I have found 2 ways to fix this but without any examples:
- do something with a proxy?
- send specific headers
More information about my problem can be found at:
- http://scn.sap.com/message/13697625#13697625
If you can't set the right headers on the server-side and you can't modify the response for jsonP you should indeed use a proxy.
A proxy script is a sort of middleware. You make a request to the script the script gets the data, and returns it to you. For example php proxy. You can make the same thing in asp, jsp, flash or even java applet.
Now you have your SAP service, a proxy (php)file in a your prefered location, and your local javascript in the same domain as the proxy. You don't even need CORS.
If you want to put the proxy in another domain you have to make sure the php file sends the right headers. (Access-Control-Allow-Origin yourdomain or Access-Control-Allow-Origin * for allow all)

How do I ensure jQuery ajax call does not send a local copy of file?

$.ajax({
type: 'GET',
url: "string.txt",
cache: false,
success: function(str){
alert("Data is: "+ str);
}
});
In this example, string.txt is sent to the cache (\Temporary Internet Files)
How do I ensure that the file is not sent. I do not want copy to be sent.
Only a read from the server. Am I missing an option?
I set cache to false but that does not block it from being sent to client.
For example, ajax POST does not send a local copy.....
Here is some background info to what i am trying to do, but with jQuery.
I am curious as to why the standard ajax post seems to have the desired functionality I am looking for and am unable to do that with jQuery?
Thanks
Or set a no cache header server-side.

Categories

Resources