javascript - jquery $.post doesn't work - javascript

I just get started in Ajax and httpRequest. While I was playing around with the code, I noticed that $.get works fine but $.post doesn't work. Here's my code:
$(document).ready(function() {
$.post('hello.txt', function(data) {
alert(data);
}).fail(function() {
alert('fail');
});
});
It always gives me a fail, and I cannot figure it out.
Thanks

Barmar is correct in the comments, but for an answer, let's go over what it is these functions are doing.
When you're using the jQuery AJAX methods, they are performing HTTP requests to the resource you're providing in the url parameter for the function. As long as the value is something sitting on your server (an endpoint) the function will hit it.
$.get() performs an HTTP GET action which is how we'd fetch data over HTTP. In your example, you specify hello.txt as the url, which as long as that is a file sitting on your server, the application will make a GET request to that resource. If it is found, the contents of that resource are returned. This can be done with a text file, a JSON payload, HTML web pages, etc. As long as the resource has returnable content, it will return that content.
$.post(), on the other hand, performs an HTTP POST action which sends data up to a resource to be processed. A POST action is not intended to fetch a resource's data, but to push data into it. Canonically, you would use a POST to create something with the data you push to the resource (as opposed to PUT for modifying and DELETE for removal, but that's beyond this answer).
So, the GET works because the action is intended to fetch data and the resource you provided has data to return. The POST fails because it is intended to give data to the resource to process, which your text file is not equipped to handle.
Hope this sheds a bit of light on the problem.

Related

jQuery event when JSON is received - one time URL

I'm trying to scrape a site that uses lots of ajax effects to show data in a table.
There is some data returned via JSON when you interact with the site.
I know the URL and how to construct it but the server returns a HTTP 410 status if I try and re-request this JSON (I guess the server is expiring the data).
I have one chance to capture the data and I'm looking for a jQuery function, something like onJSONResourceReceived would be nice so that I can catch the response and store it in a variable.
Either a callback or a way to cache the data in a variable would be great.
Or if there is already a variable that stores all JSON resource already received in memory, that is even better.
All the functions I've looked at are for situations where you know or can re-request the URL.
This question is similar but for CasperJS:
How to get the response after a POST request in CasperJS
Look at the $.ajaxSuccess
Attach a function to be executed whenever an Ajax request completes
successfully.
$(document).ajaxSuccess(function( event, request, settings ) {
});

AJAX calls - where does logic go?

This might not even be an AngularJS question and could just be an AJAX question. I'm new to the "developer" side of the frontend so bear with me.
When making an AJAX call to fetch JSON data, where does the logic behind what data is returned and viewed fall? In my mind, there would be a couple of possibilities and I want to understand which is the proper choice and why.
Let's use an example of searching and playing a Youtube video.
The logic could fall to the backend (controller), where the JSON is rendered based on some logic to give you a JSON file with exactly the right data. i.e. you search "cat videos" and when making an AJAX call, the JSON file you pull has been rendered to be only cat videos.
The opposite end would be that the Angular controller has the logic. This would imply that all data is called (cat videos along with everything else... music videos, funny videos, tutorials, and so on) and then sorted through on the client side. This, to me anyway, would be more inefficient / slow for the client, so doesn't seem to make sense. I suppose still might do some filtering of the data on the client side though. So, maybe a search for "cat videos" wouldn't return ALL videos, but definitely all cat videos and any filtering based on, say, # of views, video length, and so on would be done on the client side (vs. calling the database again for a "new" set of videos).
Not sure if this is accurate, but could you have logic in your factory to return only a portion of the data? However, I believe the entire JSON file would need to be rendered, but only portions would be returned. I guess depending on where the JSON file renders (i.e. backend or frontend) this could be similar to either option #1 or #2.
Or maybe I'm misunderstanding things entirely and the way this works is entirely different!
I'm basically looking to figure out how the scenarios of 1. user searches a term and results are shown, 2. user clicks a search result and now more detailed data of the result is on it's own page. And how this ends up working out. I'm looking for help with AngularJS, but I think this ultimately an AJAX question (single page app or not) more than anything.
There's a few critical concepts you may be confused about.
First. JSON is not a file, it's a format, more simply, a type of string. It's really good for collapsing arrays and storing address-value pairs, so a lot of data flies around in that format. Strictly speaking, they are JSON objects, but they're a lot like strings and arrays. It looks like this, if I remember correctly:
{ "name" : "john doe", "pet" : "dog", "hobby" : "parasailing" }
Second, AJAX is a request to the server, made from the client (the browser) after the original page has loaded. That is, you type in 'youtube.com' and the youtube server receives the request and sends a big pile of HTML back to your browser.
You watch your video, make a rating, and the browser doesn't reload the page but instead sends a separate request back to the youtube server with your rating. There's a parameter in the request that says "send it to ratingspage.php". This request is AJAX.
Now, the logic happens (server-side). ratingspage.php receives your request. It contacts the databases, updates or fails or whatever, and sends back a response to your browser. This response may be in JSON format.
Finally, your browser parses that response and updates the DOM (HTML document) as appropriate.
At this point, it's worth noting that if the logic happened on the client-side (browser), the user could see it - this is a security problem! So, sensitive operations should be carried out on the server side, where you can test and sanitize the request data.
In summary:
AJAX is separate from the initial load event.
Information sent is gathered from the client browser
Logic happens server-side
Logic can use whatever language the server understands (PHP, Java, Ruby, etc.)
Information is returned to the browser
Information sent and received may use JSON format
Everything client-side happens in Javascript
Here's a bare-bones ajax request (done in Javascript) with comments. This has no exception handling, state checking, or anything so don't use it! But it gives you the basic idea.
// Make a new request
var req = new XMLHttpRequest(); }
// Requests will have various states depending on whether they're processing,
// finished, error, etc. We'll assume everything went OK.
// We need to establish a handler before the request
// is sent so it knows what to do.
req.onreadystatechange = function() {
// Here's what the server sent back to the browser
alert(req.responseText);
}
// Using the GET method, set up some parameters
req.open("GET", "somelogicpage.php?blah=blee&bloo=bar", true);
// Send the request
req.send(null);
Server-side, somelogicpage.php may look like:
<?php
if ($_GET['blah'] != 'blee']) {
// This is the response text!
echo "Sorry, you need to blee when you blah.";
}
else {
// (or this)
echo "I'm ecstatic to report nothing is wrong!";
}
?>
Your alert(req.responseText) from the handler function in the previous Javascript will say whatever the PHP has dumped out.
So yes, you can use whatever portion of the request you like, and return whatever you like. Javascript kicks bleep.

Reading contents of an iframe with wikipedia source? [duplicate]

I am trying to implement a simple request to Wikipedia's API using AJAX (XMLHttpRequest). If I type the url in the address bar of Firefox, I get a neat XML, no sweat there. Yet, calling the exact same url with:
// this is my XMLHttpRequest object
httpObjectMain.open("GET", "http://en.wikipedia.org/w/api.php?action=query&format=xml&prop=langlinks&lllimit=500&titles=kaas", true);
httpObjectMain.send(null);
returns an empty response. According to FireBug, I get a 200 OK response, but the content is just empty.
I suspect I might be missing something on the header of the GET http request.
Help! (and thanks!)
The Wikipedia API does support JSONP.
Your query string'll become something like this:
http://en.wikipedia.org/w/api.php?action=query&format=json&callback=test&prop=langlinks&lllimit=500&titles=kaas
But you'll have to build the jsonp handler (or you can use your favorite library to do it), switch to json output format from the xml you choose and create the callback function to parse the result and do the stuff you need on the page.
The browser will not allow you to send an XHR to another domain other than the one the page is on. This is for security purposes.
One way around this that I have seen is to setup a proxy on the domain the page is hosted on that will pass requests through to the actual api server. See http://ajaxpatterns.org/Cross-Domain_Proxy

Synchronous cross sub-domain POST request with jQuery

I'm trying to do a cross domain POST request and have hit a wall (or two).
I can't put a proxy page on the server - so that is not an option.
I have researched getJSON, which works great except that I need to POST not GET.
Is it possible to do this? If it is not, can someone explain to me how getJSON works and why I cannot make a POST alternative.
You CANNOT make a cross-domain request (GET / POST / etc.) with an XMLHttpRequest (aka AJAX).
What you can do, when the server supports it, is make a JSONP request. A JSONP request works as follows:
jQuery creates a globally accessible function out of the callback function you provide as an argument
Instead of using XMLHttpRequest (AJAX) to make the HTTP request, jQuery dynamically inserts a SCRIPT tag into the DOM
The SRC of the script tag is the request URL to which you are trying to communicate
jQuery adds a callback param to the query string like so: example.com/someurl.js?callback=someDynamicallyGeneratedMethodName
It is then up to the SERVER to return JavaScript that your client can use by passing the JSON result as an argument to someDynamicallyGeneratedMethodName
If you have no control of the server that you are posting to, then you are out of luck, JSONP won't do you much good. Whatever the server returns will be in a SCRIPT tag, and will most likely throw an error if it isn't formatted correctly.
For more info on this, I suggest you look at the base $.ajax function instead of the shortcuts. (In the jQuery documentation under Ajax. Sorry I can't post more links)
Again, if you don't have control of the server you are posting to, you might want to look into a proxy if possible. Otherwise, an IFRAME may be your only other option. There is also a method to accomplish this with a SWF (flash) object. I have tried neither, but they are workarounds to the limitations of the XMLHttpRequest object.
Hope I could help!
You can do a post, but what you want is a JSONP request to get around the cross domain issues. Essentially you provide a callback function and the request comes back as script content and your callback gets called with the JSON data from the request. Your server side script will need to provide the data back as a function call using the callback function wrapped around the JSON object.
See the documentation on the post function.
$.post( '/example.com/controller/action?callback=?',
{ param: "data" },
function(data) {
...do something with the data...
}, 'jsonp' );
ASP.NET MVC action for this:
[AcceptVerbs( HttpVerbs.Post )]
public ActionResult Action( string param, string callback )
{
var jsonData = ...do something and construct some data in JSON...
return Content( callback + "(" + jsonData + ");" );
}
If you want to do Cross Domain POST then the easiest solution is the one provided here by Matteo.
It worked great for me

detecting JSON loaded by browser

I have an application in which most requests are submitted via AJAX, though some are submitted via "regular" HTTP requests. If a request is submitted and the user's session has timed out, the following JSON is returned:
{"authentication":"required"}
The JavaScript function which submits all AJAX requests handles this response by showing a popup message and redirecting the user back to the login page.
However, when a non-AJAX request receives this response the JSON is simply shown in the browser because the response is processed directly by the browser (i.e. the aforementioned JavaScript function is bypassed). Obviously this is not ideal and I would like the non-AJAX requests that receive this response to behave the same as the AJAX requests. In order to achieve this, I can think of 2 options:
Go through the application and convert all the requests to AJAX requests. This would work, but could also take a long time!
The JSON shown above is generated by a very simple JSP. I'm wondering if it might be possible to add a JavaScript event handler to this JSP which is run just before the content is displayed in the browser - I'm assuming this would never be called for AJAX requests? This handler could call the other JavaScript code that displays the popup and performs the redirection.
If anyone knows how exactly I can implement the handler I've outlined in (2), or has any other potential solutions, I'd be very grateful if they'd pass them on.
Cheers,
Don
3) Change your AJAX code to add a variable to the GET or POST: outputJson=1
You cannot add a handler to the JSP that way. Anything you add to it will make it a non-JSON producing page.
There are two options that I can see:
Add a parameter to the page by appending a URL parameter to the screen that modifies the output.
URL: http://domain/page.jsp?ajaxRequest=true
would output json only
URL: http://domain/page.jsp
would display a jsp page that could forward to another page.
OR
change the response to have the forwarding code in the JSP that will get executed by the web browser if it is hit directly. Then have your calling AJAX to strip the forwarding code out, and then process what is left.
4) Read up on the 'Accept' request HTTP header.
Then, on the server side tailor the output:
e.g.
if(Accept contains application/json...) { // client asking for json, likely to be XHR
return {"foo":"bar"}
} else { // other
return "Location: /login-please";
}
Start with a smarter error message, like this:
{"error":"authentication required"}
Wrap the JSON output in a callback:
errorHandler({"error":"authentication required"});
Have a handler waiting in your script:
function errorHandler(r) {
alert(r.error);
}
And don't forget to send it down as text/javascript and not application/x-json.

Categories