jQuery ajax drops integer on url - javascript

I am using this data...
// Pulled from the button that was hit
var method = document.activeElement.getAttribute('method').toUpperCase();
var url = document.activeElement.getAttribute('url');
Both buttons (methods) have the same url defined... '/user/1'
This is my jQuery AJAX call...
$.ajax({
type: method,
url: url', /* I even hard coded this to make sure what it had to use */
contentType: "application/json; charset=utf-8",
data: $(form).serializeArray(),
error: function (xhr, status) {
alert(xhr.status + ' : ' + url);
}
});
I have discovered that a PUT call truncates the number at the end of the given URL. But it has a trailing SLASH, it's OK.
If I run DELETE, it does what I expect
DELETE: /user/1
If I run PUT, I don;t get what I expect...
PUT: /user
notice the number "1" missing from that url?
I dug around and decided to try native JS... this is what I have...
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status === 200) {
var userInfo = JSON.parse(xhr.responseText);
}
};
xhr.send(JSON.stringify($(form).serializeArray()));
If I run DELETE, it does what I expect
DELETE: /user/1
If I run PUT...
PUT: /user/1
It works.
Yes, I know the URL has the "1" at the end for a PUT because I am sending the variable to the console before AND after the ajax call.
console.log(method + ': ' + url);
Besides, its the same var creation used for the native JS as used for the jQuery.
Now here's the kicker!
If the URL is defined as...
PUT: /user/walter
The name at the end stays.
Any ideas?

Related

How to get access token for an API by using POST method in JavaScript?

The API I want to get credentials for uses OAuth2.
The documentation for the API has this listed:
Request access token:
POST: auth/access_token
Url Parms:
grant_type : "client_credentials"
client_id : Client id
client_secret : Client secret
What I figured from this is that I need to send a JSON object as a string so I tried this in JavaScript.
var xhr = new XMLHttpRequest();
xhr.open("POST","url for the api",false);
var obj = {
"POST": "auth/access_token",
"Url Parms": [
{
"grant_type":'\"client_credentials\"',
"client_id": "My Client id",
"client_secret": "My Client secret"
}
]
};
var clientcred = JSON.stringify(obj);
xhr.send(obj);
All this gave me was a JSON which said I made an error.
{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the \"grant_type\" parameter."}
The code actually doesn't even work because of 'same-origin policy'. I used an extension to get around that. But I am so done. I can't figure it out. Do I need to learn something like php? How do I get my access token.
Edit:
It might need the parameters in the URL, so POST auth/access_token?grant_type=client_credentials&client_id=id‌​&client_secret=clien‌​t_secret or possibly POST auth/access_token/client_credentials/id/client_secret – Sara Tibbetts 8 hours ago
This did it. I woke up and the first thing I tried and it worked. Thank you so much #Sara Tibbetts and everyone else who tried to help me.
Edit 2:
The extension was a poor workaround, since then I have learned about Cross Origin Resource Sharing. I should've made my API call from the server rather than doing it client side, which is actually secure as well.
This is how I'm doing it in a working Prod program (It is using an auth code that I get earlier - but it doesn't matter, it's just different parameters - replace my stuff that has auth code with client secret requirements and give it a try..I think you're just trying too hard.
var xhr = new XMLHttpRequest();
I use a string for my parameters:
var data =
'resource=[my resource]' +
'&client_id=' + clientId +
'&code=' + authCode +
'&grant_type=authorization_code' +
'&response_type=token';
var dataFinal = encodeURI(data);
Then I POST it as:
xhr.open('POST', url, true);
xhr.withCredentials = true;
xhr.setRequestHeader('Access-Control-Allow-Origin', '[something]');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
//do something
}
}
xhr.send(dataFinal);
You can try something like the below. Actually the json needs to be set to the data property.
$.ajax({
type: 'POST',
url: 'https://url.com',
crossDomain: true,
data: JSON.stringify({grant_type : "client_credentials",
client_id : "My Client id",
client_secret : "My Client secret"}),
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
console.log(responseData);
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}});

Why .getjson doesnt work but .ajax does?

I'm working on Free Code Camp's wiki viewer and trying to figure out the api call. I thought getjson and ajax were equivalent but maybe i'm doing something wrong.
So at first I used this getjson code:
$.getJSON('http://en.wikipedia.org/w/api.php?action=query&list=search&format=json&srsearch=' + search,
function(api){
console.log(api);
}, 'jsonp');
but it returned this error: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Then I used ajax with the same url:
$.ajax({
url: 'http://en.wikipedia.org/w/api.php?action=query&list=search&format=json&srsearch=' + search,
dataType: 'jsonp',
success: getWiki //just console logs the api
});
and this seemed to return the api call. Can anyone explain why getjson didnt work but ajax did?
You're missing the required callback=? query parameter to force $.getJSON to perform a JSONP request
$.getJSON('http://en.wikipedia.org/w/api.php?callback=?', {
action: 'query',
list: 'search',
format: 'json',
srsearch: search
}, api => {
// response handler
})
See http://api.jquery.com/jquery.getjson/#jsonp
This is my solution also I left an alternative using only JavaScript
NOTE I added this &origin=* param in the url to make it work using this the original jQuery code.
var search = 'php';
var searchURL = 'https://en.wikipedia.org/w/api.php?action=query&format=json&generator=search&origin=*&gsrsearch=' + search;
// Using JSON
$.getJSON(searchURL, function(data){
var read = JSON.stringify(data);
console.log('Using jQuery: ' + read);
}, 'jsonp');
// Using JavaScript
var getJSON = function(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status == 200) {
callback(null, xhr.response);
} else {
callback(status);
}
};
xhr.send();
};
getJSON(searchURL, function(err, data) {
if (err != null) {
alert('Something went wrong: ' + err);
} else {
var read = JSON.stringify(data);
console.log('Using JavaScript: ', read);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

JavaScript equivalent for jQuery's $.ajax function

I have the following jQuery code:
dataString = 'test'; // array?
$.ajax({
type: "POST",
url: "tokenize.php",
data: {
data: dataString
},
cache: false,
success: function (data) {
returnedvalue = data;
console.log(data); //alert isn't for debugging
}
});
This jQuery code is working fine, but I want a plain JavaScript version of this code which I'm not able to figure out how to do. I made up this code with help from Stack Overflow only.
I have seen that this can be done using XMLHttpRequest:
var http = new XMLHttpRequest();
var url = "tokenize.php";
var params = "lorem=ipsum&name=binny"; // What will be done here in my case?
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
// Call a function when the state changes.
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
The format of application/x-www-form-urlencoded data is:
key=value&key=value&key=value
Run each key and value through encodeURIComponent to deal with characters that have special meaning or that aren't allowed in the encoding.

How to override Backbone.sync so it adds the apikey and username at the end?

I am using backbone-tastypie, but I am having the toughest time getting it to work properly. In Tastypie, I am using ApiKeyAuthentication for my resources, so every ajax request, I need to append the apikey and username to the end of a request or send additional headers that add on the username and api key.
I am trying to remove a view and its model using backbone with the following code:
// Remove the goal update view from the DOM
removeItem: function() {
this.model.destroy({wait: true, success: function() {
console.log("success");
}, error: function() {
console.log("error");
}});
},
After the function executes, the browser tries to do a GET request on the following URL:
:8000/api/v1/update/2/
It does not include the api_key or username at the end, and it has a trailing slash at the end of the url. I think it is trying to use Backbone.oldSync to do the GET request. How would I make it so the sync does include the username/api key at the end and removes the trailing slash?
In all of the other requests, I have made it so the api key and username is appended to the end of the http request by adding the following code to backbone-tastypie:
if ( !resp && ( xhr.status === 201 || xhr.status === 202 || xhr.status === 204 ) ) { // 201 CREATED, 202 ACCEPTED or 204 NO CONTENT; response null or empty.
var location = xhr.getResponseHeader( 'Location' ) || model.id;
return $.ajax( {
url: location + "?" + "username=" + window.app.settings.credentials.username + "&api_key=" + window.app.settings.credentials.api_key,
success: dfd.resolve,
error: dfd.reject,
});
}
Let's explore the possibilities
Using headers
Backbone.sync still just uses jQuery ajax so you can override ajaxSend and use headers to send information along.
$(document).ajaxSend(function(e, xhr, options)
{
xhr.setRequestHeader("username", window.app.settings.credentials.username);
xhr.setRequestHeader("api_key", window.app.settings.credentials.api_key);
});
Using Ajax Options
If you need to send the information in just one or two locations, remember that the destroy, fetch, update and save methods are just shortcuts to the ajax caller. So you can add all jQuery ajax parameters to these methods as such:
// Remove the goal update view from the DOM
removeItem: function ()
{
this.model.destroy({
wait: true,
success: function ()
{
console.log("success");
},
error: function ()
{
console.log("error");
},
data:
{
username: window.app.settings.credentials.username,
api_key: window.app.settings.credentials.api_key
}
});
}
Overriding jQuery's ajax method
Depending on your needs, this might be the better implementation (note that this is no production code, you may need to modify this to fit your needs and test this before using it)
(function ($) {
var _ajax = $.ajax;
$.extend(
{
ajax: function (options)
{
var data = options.data || {};
data = _.defaults(data, {
username: window.app.settings.credentials.username,
api_key: window.app.settings.credentials.api_key
});
options.data = data;
return _ajax.call(this, options);
}
});
})(jQuery);
Just for future readers of this post, when you do a model.destroy() you can't pass any data because the delete request doesn't have a body, see this issue for more info:
https://github.com/documentcloud/backbone/issues/789

How to pass data while using get method in xdr

As IE does not support cross domain issues, we have to use get or post method by using xdr, my problem is, I don't know how to pass data while using get method with xdr.
Code snippet for get method using jquery ajax is like -
$.ajax({
type: 'GET',
cache: false,
url: site_url,
data: params,
success: onsuccess,
error:onError
});
but suppose if I write this code for xdr it will be like -
var xdr = new XDomainRequest();
xdr.CacheControl = "no-cache";
xdr.open("get", site_url);
xdr.onload = function () {
var data = $.parseJSON(xdr.responseText);
onsuccess(data);
}
xdr.onerror = function() {alert('err');};
xdr.send();
Now in this, I do not know where to pass data!!!
Please help me out to solve this problem.
It all happens in the ".open" method.
Lets say you want to pass some JSON or an object to the request.
Do it like so...
var my_request_data = {
"whatever" : "whatever",
"again" : "whatever again",
"you get" : "the point..."
};
my_request_data = $.param(my_request_data);
xdr.open("get", "http://url.com/to/get/or/post/too/" + my_request_data);
jQuery turns the JSON object into URL friendly params and then it is sent to the server.
That is how you pass data!

Categories

Resources