I would like to make an async GET request that returns back a document with MIME content type and cause it to bring the browser's 'Save' dialog.
Previously, I used to make a regular HTTP (non-async) call through a link and the returned response had a 'Content-Type' and 'Content-Disposition' like so:
Content-Type: text/plain
Content-Disposition: attachment;
filename=genome.jpeg;
modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
Is there a way to convert this to jQuery's $.ajax() GET request?
The $.ajax method only supports the dataTypes, "xml", "html", "script", "json", "jsonp", and "text". Would my response data-type fall into one of these categories?
My request looks like this:
$.ajax({url: myUrl,
data: params,
type: "GET",
success: function(data)
{
console.log("try to save this file!");
},
error: function(req, status, errThrown){
alert("ERROR: Something happened");
}
In the 'success' callback, I see the file contents passed back in the 'data' variable as a plain text but need the 'save' dialog to get launched on the browser.
The server IS sending back the response with the correct headers set.
There is no way I know of to get a true Ajax request to pop a save dialog up. This has nothing to do with the headers sent by the server.
If you'd like to programatically pop a save dialog box, you can use jQuery to append a hidden iframe to the page with the URL as it's src. This should pop the dialog box as necessary.
That's something the server has to do. There's nothing you can do from the client side that will force an unwilling server to set response headers.
Related
I noticed that we don't need to include dataType: "json" in our AJAX call if the server file is already in .json format, e.g.
index.html
$.ajax({
url: "ajax/test.json",
data: "id="+id,
cache: false,
type: "POST",
success: function(response){
// Some more stuff here...
}
});
test.json
{
"fname" : "Aileen",
"lname" : "Brown",
"email" : "ab#gmail.com",
"phone" : "1234567890",
"country" : "USA"
}
But if we have to fetch above content from a PHP file through MySQL database
index.html
$.ajax({
url: "ajax/test.php",
data: "id="+id,
cache: false,
type: "POST",
dataType: "json",
success: function(response){
// Some more stuff here...
}
});
test.php
<?php
$data = array(
"fname" => "Aileen",
"lname" => "Brown",
"email" => "ab#gmail.com",
"phone" => "1234567890",
"country" => "USA"
);
// Convert PHP array into JSON object
echo json_encode($data);
?>
The response from this server PHP file via AJAX call in web browser console is collected in the same JSON format as my test.json file has.
{"fname":"Aileen","lname":"Brown","email":"ab#gmail.comk","phone":"1234567890","country":"USA"}
Can anyone please explain me properly why using dataType: "json" is mandatory when the data has to be fetched from a PHP file rather than a JSON file if the format of data coming from server is identical?
In short, this is because of a bug in your PHP code.
Any HTTP request or response with a body has a matching Content-Type in the headers to describe what type of data it is.
By default, jQuery will parse the response it gets according to the Content-Type header it came with. dataType causes it to ignore that header (and also set an Accept header on the request).
Most web servers these days are configured by default so that a file with a .json file extension gets a Content-Type: application/json header.
Any PHP program will output, again by default, a Content-Type: text/html header unless overridden using the header function.
Since your PHP doesn't include header("Content-Type: application/json") it tells the web browser that it is sending HTML and jQuery tries to parse the JSON as if it were HTML.
This is because the Content-Type sent in the header for a .json file is already application/json whereas a "normal" PHP file has text/html.
jQuery AJAX uses "Intelligent Guess" to determine the data type from the MIME type of the file if no dataType is set:
The type of data that you're expecting back from the server. If none is specified, jQuery will try to infer it based on the MIME type of the response (an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string).
(see https://api.jquery.com/jQuery.ajax/)
You can easily watch this behavior in your Developer Console (here I used Firefox's built-in version):
I want to load the shopping cart whenever the page is loaded but nothing happens. The console log is not telling me anything either. I have a post to cart system that works fine, so I cant figure out why this doesnt work.
I am using Laravel with a shopping cart plugin.
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'get',
url: '{{route("getCart")}}',
error: function(data) {
var errors = data.responseJSON;
console.log(errors);
},
dataType: 'json',
success: function(data) {
$('#cartResult').html(data.cartCount)
},
});
});
public function cartGet()
{
$cartCount = Cart::content() - > count();
$data = array('cartCount' => $cartCount);
echo json_encode($data);
}
Try return json_encode($data); instead of echo.
You can also avoid json_encode and just use return $data;.
Simply return $data, laravel will place the correct header in response.
if you return json_endode($data) a Content-type: text/plain header will be placed,
if you return $data (which is a structure) laravel will json_encode under the hood and place a Content-type: application/json header.
your code should look like this:
public function cartGet()
{
return ['cartCount' => Cart::content()->count()];
}
It might be because in your $.ajax call you've set dataType: 'json'
From the docs:
As of jQuery 1.5, jQuery can convert a dataType from what it received
in the Content-Type header to what you require. For example, if you
want a text response to be treated as XML, use "text xml" for the
dataType. You can also make a JSONP request, have it received as text,
and interpreted by jQuery as XML: "jsonp text xml". Similarly, a
shorthand string such as "jsonp xml" will first attempt to convert
from jsonp to xml, and, failing that, convert from jsonp to text, and
then from text to xml.
When you echo json_encode(), it sends the data straight to the php output stream buffer and Laravel doesn't know that it needs to add a Content-Type: application/json header to its response. Without it, maybe jQuery needs the dataType to be "text json"?
As others have mentioned, you can return $data from your controller. Laravel will automatically cast your array to json, and it will also set the appropriate Content-Type headers. Maybe try that first?
I just created an JQuery ajax function to retrieve some json-encoded data from PHP, here's my code :
file name : bank.php
$('form').on('submit', function(){
var datatobesent = $(this).serialize();
$.ajax({
data: datatobesent,
url:'data.php',
type:'GET'
})
.done(function(data){
console.log(typeof(data));
});
return false;
})
and in data.php I wrote
if(isset($_GET)){
$data = $_GET;
echo json_encode($data);
header("Content-type:application/json");
}
the question is, when I delete the line of header("Content-type:application/json"); in data.php the console.log tell that the type of data returned by ajax is string.
And when I added dataType :json`` inside the ajax function in bank.php the type changes into object
so what is the function of header("Content-type:application/json"); actually?
The function header("Content-type:application/json") sends the http json header to the browser to inform it what kind of data it expects. You can see all the http headers for each request in your browser (If you are using chrome open developer tools, go to network, adjust the view and reload the page, you will see all requests made by your browser, if you click on any on any of these requests then click on headers you will see the headers of each request).
When you use this function you will notice the http header Content-Type:application/json in the response sent from the server. If you don't use it the server will send the default which most likely is Content-type:text/html; charset=UTF-8
As #Monty stated you don't need this function if you added dataType: 'json' to your AJAX as Jquery will handle the data even it is sent with text/html header.
See Also: jQuery AJAX Call to PHP Script with JSON Return
To read more about headers : http-headers-for-dummies
I have an ajax call, that sends form data to a php function. Since I read a lot that using contentType: 'application/json' is best practice I wanted to give it a try as well. But unfortunately my script doesn't return anything when I use it. If I remove it, the script does what it is supposed to do.
Do you have any idea what the reason might be and why? Thank you!
$('#Form').submit(function(e) {
e.preventDefault();
var content = $(this).serialize() + "&ajax=1";
$.ajax('app/class/controller/contactForm.php', {
type: "POST",
//contentType: 'application/json',
dataType: 'json',
data: content,
success: function(result) {
console.log(result);
}
});
})
and my PHP:
if(isset($_POST['ajax']) && $_POST['ajax'] === '1') {
echo json_encode(validateForm($_POST));
}
When using contentType: 'application/json' you will not be able to rely on $_POST being populated. $_POST is only populated for form-encoded content types.
As such, you need to read your data from PHP raw input like this:
$input = file_get_contents('php://input');
$object = json_decode($input);
Of course if you want to send application/json you should actually send JSON, which you are not doing. You either need to build the object serialization to JSON directly, or you need to do something like this - Convert form data to JavaScript object with jQuery - to serialize the object from the form.
Honestly in your case, since you are dealing with form data, I don't quite think the use case for using application/json is there.
The best practice you refer to is about the server script setting the Content-Type for JSON to "application/json":
Header('Content-Type: application/json; charset=UTF8');
This is because otherwise a default Content-Type will be sent, often a catch-all text/html, and this could lead to an incomprehension with the client.
If you do not specify yourself a Content-Type in the jQuery request, jQuery will determine the most appropriate one. The problem here is that you were sending a POST form, for which the default Content-Type set by jQuery is application/x-www-form-urlencoded, which tells PHP to decode the data as POST fields and populate $_POST. Your script would have then recovered its parameters from $_POST (or maybe $_REQUEST).
By changing it to application/json, $_POST will no longer be populated, the receiving script operation won't receive the parameters where it was expecting to, and the operation breaks.
So you either need to:
not specify the Content-Type yourself (better, IMHO)
set a Content-Type of application/x-www-form-urlencoded; charset=UTF-8
set a Content-Type of application/json; charset=UTF-8 and modify the script to parse the POST stream and decode the JSON data; see this answer.
The third option requires proper handling of php://input.
The PHP script should be setting the Content-Type header.
if(isset($_POST['ajax']) && $_POST['ajax'] === '1') {
header('Content-Type: application/json');
echo json_encode(validateForm($_POST));
}
I am making an ajax request from a jquery script to one of my ajax controllers in codeigniter. This process works fine when using data type json. However, when I want to send xml back from the server, the jquery documentation says that the server must specify a MIME type of text/xml. How do I do this with codeigniter.
My ajax call looks like this:
$.ajax({
type: "POST",
url: siteUrl + "index.php/ajax_controller/test",
dataType: "xml",
success: testSuccess
});
You can specify a content type header using the following code. You could put it at the top of your controller method in CI:
header("Content-Type: text/xml");
It must be before any output starts, so use it before you call your first $this->load->view().