BackBone - best way to send a server request - javascript

I'm new to Backbone and am just getting familiar with it.
I have a model and a collection - and view to the collection and a Form.
I'm sending request to get/get all/create by doing form.submit(), or something similar - which calls for the correct type [GET/POST/PUT] to the server using the base URL in the collection/model.
how do i send a non-trivial request? say that my base URL is /some/url , and i want to send /some/url/doSomething. should i directly send an ajax request with this URL or does backbone handle this in a more simpler way?
Thanks!

In backbone, you can pass url as an option to your model.fetch, model.save requests, etc to override the default declared in the model. You don't need to manually form an ajax request with $.ajax or anything like that.

If your URL does not pertain to a particular resource/model/collection, you may use raw jQuery ajax requests.
$.ajax({
method: 'GET',
url: '/some/url',
success: function(resp) { //handle response}
})

Best example of REST API is github api
example of merge a pull request (Merge Button):
PUT /repos/:owner/:repo/pulls/:number/merge
The main goal is using resources instead a commands. For example:
REST:
PUT /repos/:owner/:repo/pulls/:number/merge
{"commit_message":"mesg"}
NO-REST:
POST /merge
{"commit_message": "mesg", "owner": 123, "repo":"asd", "number": 1}
Cheers

Related

Cookies being passed when loading resource but not ajax?

Setup is I have one Rails app setup to act as an JSON API and another static html page that I want to use to call the API. For sake of argument the rails API is at foo.com and the static html page is at bar.com.
On the foo.com app I have something like this:
if !cookies[:foo]
cookies[:foo] = "testing #{rand(500)}"
else
logger.info(cookies[:foo])
render :json => { :cookie => cookies[:foo] }
When I try to do a ajax GET request with jquery from bar.com the cookie does not get sent back to the JSON API.
$.get('http://foo.com/', function(data){console.log(data)})
But If I load the page a resource I can get the cookies to send back and forth between foo.com and bar.com
<script type="text/javascript" src="http://foo.com"></script>
Does anyone know why I am able to pass cookies back and forth cross-domain when loading the script as a script resource and not when I do a simple ajax request? Any way around this?
Use $.ajax as you need to make a JSONP request coz your ajax call is cross site.
$.ajax({
url: "xxxx",
crossDomain : true,
dataType : 'json',//if response is in JSON Notation
success : function (result){
alert(result);
}
});
Just as techie said, you need to use $.ajax and make a json(p) request in order for cross domain to be enabled.
Cookies are tricky with this sort of implementation though. even if you manage to send your cookies back and forth using some sort of hack, older (or cheaper) browsers will block them.
*cough* IE *cough*
A simple way to "hack" around this is to pass the cookie in the url, like so:
$.ajax({
url: "//domain.com/path/to/stuff;cookie1=value1?someParameter2=value2",
crossDomain : true,
dataType : 'json',//if response is in JSON Notation
success : function (result){
alert(result);
}
});
In this example, I've told my server that my request has a cookie name "cookie1" with a value of "value1" and a GET parameter with a value of "value2"
Hope this helps.

Calling a web service in JQuery and assign returned Json to JS variable

This is my first time attempting working with JQuery, Json AND calling a web service.. So please bear with me here.
I need to call a webserivce using JQuery, that then returns a Json object that I then want to save to a javascript variable. I've attempted writing a little something. I just need someone to confirm that this is indeed how you do it. Before I instantiate it and potentially mess up something on my company's servers. Anyways, here it is:
var returnedJson = $.ajax({
type: 'Get',
url: 'http://172.16.2.45:8080/Auth/login?n=dean&p=hello'
});
So there it is, calling a webservice with JQuery and assigning the returned jsonObject to a javascript variable. Can anyone confirm this is correct?
Thanks in advance!
var returnedJson = $.ajax({
type: 'Get',
url: 'http://172.16.2.45:8080/Auth/login?n=dean&p=hello'
});
If you do it like this returnedJson would be an XHR object, and not the json that youre after. You want to handle it in the success callback. Something like this:
$.ajax({
// GET is the default type, no need to specify it
url: 'http://172.16.2.45:8080/Auth/login',
data: { n: 'dean', p: 'hello' },
success: function(data) {
//data is the object that youre after, handle it here
}
});
The jQuery ajax function does not return the data, it returns a jQuery jqHXR object.
You need to use the success callback to handle the data, and also deal with the same origin policy as Darin mentions.
Can anyone confirm this is correct?
It will depend on which domain you stored this script. Due to the same origin policy restriction that's built into browsers you cannot send cross domain AJAX requests. This means that if the page serving this script is not hosted on http://172.16.2.45:8080 this query won't work. The best way to ensure that you are not violating this policy is to use relative urls:
$.ajax({
type: 'Get',
url: '/Auth/login?n=dean&p=hello'
});
There are several workarounds to the same origin policy restriction but might require you modifying the service that you are trying to consume. Here's a nice guide which covers some of the possible workarounds if you need to perform cross domain AJAX calls.
Also there's another issue with your code. You have assigned the result of the $.ajax call to some returnedJson variable. But that's not how AJAX works. AJAX is asynchronous. This means that the $.ajax function will return immediately while the request continues to be executed in the background. Once the server has finished processing the request and returned a response the results will be available in the success callback that you need to subscribe to and which will be automatically invoked:
$.ajax({
type: 'Get',
url: '/Auth/login?n=dean&p=hello',
success: function(returnedJson) {
// use returnedJson here
}
});
And yet another remark about your code: it seems that you are calling a web service that performs authentication and sending a username and password. To avoid transmitting this information in clear text over the wire it is highly recommended to use SSL.

How to send data in request body with a GET when using jQuery $.ajax()

The service API I am consuming has a given GET method that requires the data be sent in the body of the request.
The data required in the body is a list of id's separated by hypen and could potentially be very large and thus it must be sent in the body otherwise it will likely foobar somewhere in the browsers/proxies/webservers etc chain. Note I don't have control over the service or API so please don't make suggestions to change it.
I am using the following jQuery code however observing the request/response in fiddler I can see that the "data" I am sending is ALWAYS converted and appended to the query string despite me setting the "processData" option to false...
$.ajax({
url: "htttp://api.com/entity/list($body)",
type: "GET",
data: "id1-id2-id3",
contentType: "text/plain",
dataType: "json",
processData: false, // avoid the data being parsed to query string params
success: onSuccess,
error: onError
});
Anyone know how I can force the "data" value to be sent in the body of the request?
In general, that's not how systems use GET requests. So, it will be hard to get your libraries to play along. In fact, the spec says that "If the request method is a case-sensitive match for GET or HEAD act as if data is null." So, I think you are out of luck unless the browser you are using doesn't respect that part of the spec.
You can probably setup an endpoint on your own server for a POST ajax request, then redirect that in your server code to a GET request with a body.
If you aren't absolutely tied to GET requests with the body being the data, you have two options.
POST with data: This is probably what you want. If you are passing data along, that probably means you are modifying some model or performing some action on the server. These types of actions are typically done with POST requests.
GET with query string data: You can convert your data to query string parameters and pass them along to the server that way.
url: 'somesite.com/models/thing?ids=1,2,3'
we all know generally that for sending the data according to the http standards we generally use POST request.
But if you really want to use Get for sending the data in your scenario
I would suggest you to use the query-string or query-parameters.
1.GET use of Query string as.
{{url}}admin/recordings/some_id
here the some_id is mendatory parameter to send and can be used and req.params.some_id at server side.
2.GET use of query string as{{url}}admin/recordings?durationExact=34&isFavourite=true
here the durationExact ,isFavourite is optional strings to send and can be used and req.query.durationExact and req.query.isFavourite at server side.
3.GET Sending arrays
{{url}}admin/recordings/sessions/?os["Windows","Linux","Macintosh"]
and you can access those array values at server side like this
let osValues = JSON.parse(req.query.os);
if(osValues.length > 0)
{
for (let i=0; i<osValues.length; i++)
{
console.log(osValues[i])
//do whatever you want to do here
}
}
Just in case somebody ist still coming along this question:
There is a body query object in any request. You do not need to parse it yourself.
E.g. if you want to send an accessToken from a client with GET, you could do it like this:
const request = require('superagent');
request.get(`http://localhost:3000/download?accessToken=${accessToken}`).end((err, res) => {
if (err) throw new Error(err);
console.log(res);
});
The server request object then looks like {request: { ... query: { accessToken: abcfed } ... } }
You know, I have a not so standard way around this. I typically use nextjs. I like to make things restful if at all possible. If I need to make a get request I instead use post and in the body I add a submethod parameter which is GET. At which point my server side handles it. I know it's still a post method technically but this makes the intention clear and I don't need to add any query parameters. Then the get method handles a get request using the data provided in the post method. Hopefully this helps. It's a bit of a side step around proper protocol but it does mean there's no crazy work around and the code on the server side can handle it without any problems. The first thing present in the server side is if(subMethod === "GET"){|DO WHATEVER YOU NEED|}

Backbone js with JSONP

I have a simple backbone application, which has struts controller as its backend and it was working fine. Then I tried to include cross domain request handling logic and I came to know that there are 2 ways to make cross domain request
JSONP
CORS
Now what I'm trying to do is, if the browser is not supporting CORS.. Then I'll have to make JSONP request. I'm done with CORS (just added header using filter) and this part is working, but I'm not able to make JSONP request successfully.
My questions regarding this are:
What should be the response from server (struts controller) be? Does it return something like function call? As of now it is returning model.
In Backbone js, overriding only the Backbone.sync to have its datatype as JSONP is enough?
Note: I'm getting the following error for my JSONP call:
Error: jsonpCallback was not called
Code: I overrided my sync in collection. My Sync function is
sync: function(method, model, options) {
options.dataType = 'jsonp';
options.url="http://localhost:8084/CrossDomain_backbone/messages.json";
//options.contentType='application/json-p';
options.error=this.errorr;
return Backbone.sync(method, model, options);
}
,
parse: function(resp){
alert('inside parse..');
return resp.model;
},
errorr:function(response,responseText)
{
alert('inside callback..: ' + responseText);
},
Thanks.
Your Struts code will need to return a function call which contains the data.
The url request might look something like this:
options.url="http://localhost:8084/CrossDomain_backbone/messages.json?callback=?";
The callback part of the query string will automatically be substituted with a random function name that your Struts code will need to use.
For example, when the JSONP request is made, jQuery (used by Backbone) might look like this:
http://localhost:8084/CrossDomain_backbone/messages.json?callback=jQuery17205394351207651198_1336231056100
So, your Struts code will read the callback parameter and emit JavaScript something like this:
jQuery17205394351207651198_1336231056100({
"name": "Henry T Ford",
"company": "Ford Motor Company",
"modified": "2012-04-05T15:06:36Z"});
jQuery handles creating a temporary function with that random name to receive the response and pass it to the defined success method.

jQuery .getJSON vs .post which one is faster?

Using
$.getJSON();
or
$.post();
I'm trying to send some parameters through a page that is just for AJAX request
and get some results in JSON or html snippet.
What I want to know is that which one is faster?
Assume the HTML file would be simply plain boolean text (true or false)
As others said there is no real difference between the two functions, because both of them will be sent by XMLHttpRequest.
If the server is handling both of the requests with the same code then the handling times should be the same.
Therefore the question can be translated to which one is faster the HTTP GET request or the POST request?
Because the POST request needs two additional HTTP headers (Content-Type and Content-Length) comparing to the GET request the latter should be faster (because less data will be transferred).
But that's just the speed, I think it's better to follow the REST guidelines here. Use POST if you're modifying something, use GET if you want to fetch something.
And one another important thing, GET responses could be cached, but I was having problems caching POST ones.
i dont think it will make a difference both make use of ajax, .post loads the data using http post request where as getJSON uses a http get request more over you dont have to explicitly tell getJSON the dataType
If it is a HTTP action that is retrieving data from the server without persisting (updating) anything, GET is the correct semantic to use.
Both post and get use HTTP so performance difference will be negligible, especially considering the variables of WAN communication.
They are both wrappers/shorthand methods for jQuery.ajax, so there wont be a performance difference.
This is old but ...
We all have to remember about: CSRF/XSRF.
If you do it this way:
$.ajax({
type: "POST",
dataType: "json",
url: url,
data: {
token : 'pass-some-security-token-here'
},
cache: false,
success: function(data) {
//do your stuff here
}
});
you can receive it then like this, nullifying most CSRF/XSRF
if (isset($_POST['token'])) { //you can also test token further
//do your stuff her and send back result
} else {
//error: sorry, invalid, or no security token
}
In many cases GET is an invitation for bad guys, as getJSON uses GET HTTP request.
$.getJSON(); is a shortcut to $.ajax(); which also calls $.post(); so you won't see much difference (but it will be easier to use $.getJSON() directly).
See the jquery doc
[EDIT] NimChimpsky was faster than me...
There are no difference, Because both are using XMLHttpRequest.
First, $.getJSON() is a shorthand Ajax function, which is equivalent to:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
https://api.jquery.com/jQuery.getJSON/
Second, $.post() is also a shorthand Ajax function, which is equivalent to:
$.ajax({
type: "POST",
url: url,
data: data,
success: success,
dataType: dataType
});
https://api.jquery.com/jquery.post/

Categories

Resources