Due to my cross domain errors, I am trying to convert my $http call to a JSONP one.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:5000' is therefore not allowed
access.
I'm a beginner and having extracted my GET service from my controller, I'm struggling with finding the spot where to change $http to $http.jsonp(url) based on the Angular documentation
Here's my service.js:
.service('NCAAF',function($http, $ionicLoading) {
return {
get: function() {
$ionicLoading.show({
template: 'Loading...',
delay: 300
})
return $http (
{
method: 'GET',
cache: true,
crossDomain: true,
dataType: 'jsonp',
url: 'https://www.kimonolabs.com/api/[key]?callback=JSON_CALLBACK',
headers: {
'authorization': 'Bearer [auth]'
}
});
}
};
})
and controller.js:
.controller('NCAAFCtrl', function ($scope, NCAAF, $ionicPopup, $ionicLoading) {
var doGet = function() {
NCAAF.get().
success(function (data) {
$scope.data = data['results']['collection1'];
$ionicLoading.hide();
}).
error(function () {
$ionicLoading.hide();
var alertPopup = $ionicPopup.alert({
title: 'Something went wrong',
template: 'Try reloading in a few seconds.'
});
alertPopup.then(function() {
console.log('Fix this ish');
});
}).
finally(function() {
$scope.$broadcast('scroll.refreshComplete');
});
};
$scope.doRefresh = function() {
doGet();
};
doGet();
})
JSONP can make you do cors request ,but that doesn't mean you will be able to get correct response.
JSONP requires you to wrap your JSON response into a Javascript function call.
When you do a JSONP the request , query string will set a parameter called
'callback' that will tell your server how to wrap the JSON response.
The server should use the callback parameter from the request string to set the
response accordingly.
So the response should be
callback([ {“access_token”: “asdfsd”, “expires”: “86400" ,"type" : "bearer"}
]);
In angular it will look like
angular.callbacks._0([ {“access_token”: “asdfsd”, “expires”: “86400" ,“type” :
“bearer”} ]);
But just for your information about how to make jsonp call ,change your code
return $http (
{
method: 'GET',
cache: true,
crossDomain: true,
dataType: 'jsonp',
url: 'https://www.kimonolabs.com/api/[key]?callback=JSON_CALLBACK',
headers: {
'authorization': 'Bearer [auth]'
}
});
to
return $http.jsonp('https://www.kimonolabs.com/api/[key]?callback=JSON_CALLBACK',{
headers: {
'authorization': 'Bearer [auth]'
}
});
Related
I am trying to convert an Ajax call with WSSE authentication to an AngularJS factory.
The method is Post.
The intended use of this is to access the Adobe Analytics Rest API and return data to be converted to JSON and then visualised with d3.js.
I am not familiar with the properties that can be used in an AngularJS $http post call and so not sure what is the correct way to do the WSSE auth, dataType, callback etc.
This is the original ajax code which came from a public github repo:
(function($) {
window.MarketingCloud = {
env: {},
wsse: new Wsse(),
/** Make the api request */
/* callback should follow standard jQuery request format:
* function callback(data)
*/
makeRequest: function (username, secret, method, params, endpoint, callback)
{
var headers = MarketingCloud.wsse.generateAuth(username, secret);
var url = 'https://'+endpoint+'/admin/1.4/rest/?method='+method;
$.ajax(url, {
type:'POST',
data: params,
complete: callback,
dataType: "text",
headers: {
'X-WSSE': headers['X-WSSE']
}
});
}
};
})(jQuery);
This is the current way the code is being used with pure JS:
MarketingCloud.makeRequest(username, secret, method, params, endpoint, function(response) {
data = JSON.parse(response.responseText);
});
I want to convert this to a factory and a controller respectively.
This is what I have done for the factory so far:
app.factory('mainFactory', ['$http', function($http) {
var wsse = new Wsse ();
return function(username, secret, method, params, endpoint) {
return $http({
method: 'POST',
url: 'https://' + endpoint + '/admin/1.4/rest/?method=' + method,
data: params,
headers: {
'X-WSSE': wsse.generateAuth(username, secret)['X-WSSE']
},
dataType: 'text',
});
};
}]);
And this is what I have for the controller:
app.controller('mainController', ['$scope', 'mainFactory', function($scope, mainFactory) {
mainFactory.success(function(data) {
$scope.data = data;
});
}]);
Currently I get an error saying mainFactory.success is not a function which I assume is because the factory isn't working yet.
I have resolved this question myself. The parameters I was passing to the first function in the factory were globally defined already and therefore getting over-written.
The first function is not required anyway.
Here is the factory code:
app.factory('mainFactory', ['$http', function($http) {
var wsse = new Wsse ();
return {
getAnalytics : function (){
$http({
method: 'POST',
url: 'https://' + endpoint + '/admin/1.4/rest/?method=' + method,
data: params,
headers: {
'X-WSSE': wsse.generateAuth(username, secret)['X-WSSE']
}
})
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}
};
}]);
And here is the controller code:
app.controller('mainController', ['$scope', 'mainFactory', function($scope, mainFactory) {
$scope.title = "Inn Site";
$scope.data = mainFactory.getAnalytics();
}]);
I have a problem when you submit parameters using $ http.post in angular.
I assume it's some sort of error itself have little knowledge of angular , because in jquery work fine.
Request jquery'javascript
var user = $('#usuariotxt').val();
var pass = $('#passwordtxt').val();
var login= {
Usuario : user,
Password : pass
};
$.ajax({
type: 'POST',
url: 'http://190.109.185.138/Apipedro/api/login',
data: login,
datatype: 'json'
}).done(function(data) {
console.log(data);
});
Request Angular-Javascript
var app;
app = angular.module('AppUPC',[]);
app.controller('Formulario',['$scope', '$http', function ($scope, $http){
$scope.login = function(){
var login = {
Usuario: $scope.usuariotxt,
Password: $scope.passwordtxt
};
console.log(login);
var url, method;
url = 'http://190.109.185.138/Apipedro/api/login';
method = 'POST';
$http.post("http://190.109.185.138/Apipedro/api/login", {},
{params: {Usuario:$scope.usuariotxt, Password:$scope.passwordtxt}
}).success(function (data, status, headers, config) {
$scope.persons = data;
console.log($scope.persons);
}).error(function (data, status, headers, config) {
$scope.status = status;
console.log($scope.status);
});
};
}]);
I have also used many other forms , including the most common
$http({
url: url,
method: method,
data: login,
headers :{'Content-Type':'application/json'}
})
Errors that occur to me are the following
Short answer: If you want to send the same data as the jQuery example, use this
app.controller('Formulario', ['$scope', '$http', '$httpParamSerializer', function ($scope, $http, $httpParamSerializer) {
// snip
$http.post(url, $httpParamSerializer(login), {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(function success(response) {
$scope.persons = response.data;
}, function error(response) {
$scope.status = response.status;
});
}]);
This is because jQuery by default sends POST data as an x-www-form-urlencoded string, ie
Usuario=dfvides&Password=dfvids
Using the code above, Angular will send an identical request to jQuery.
Angular by default sends POST data as JSON with the Content-Type header set to application/json, ie
{"Usuario":"dfvides","Password":"dfvids"}
Is your API even set up to handle a JSON payload?
The reason your Angular version was triggering a pre-flight OPTIONS request (which it appears that your API is not equipped to handle) was because the header Content-Type: application/json makes the request non-simple...
A simple cross-site request is one that:
Only uses GET, HEAD or POST. If POST is used to send data to the server, the Content-Type of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.
Does not set custom headers with the HTTP Request (such as X-Modified, etc.)
(function(){
app = angular.module('mySupport',['ngRoute']).controller('knwCenterCtrl');
var config = {
headers : {
'Accept': 'application/vnd.*********+json',
'Accept-Encoding': 'gzip,deflate',
'custom-header': '12345',
'Access-Control-Request-Headers': 'Accept, custom-header'
},
responseType: 'json'
};
app.controller('knwCenterCtrl', function($scope, $http) {
$http.get("https://abcdefg.com/support/pub/navigation/products", config)
.success(function(response)
{
$scope.prodFam = response.productFamily;
// console.log($scope.mycases);
});
});
})();
What am I missing in this get request? I was able to successfully invoke another APi from the same server using the same code. But for some reason, the code is not making any call to the server. Why is that? Please help.
Thanks,
I like to send a custom header on every request with an angularjs resource. Before every request the header has to be created again. The following doesn't work. The header is calculated only once and because of this only one request works. A second request on the same resource fails. Its a lot of copy n paste of "headers: authhandler.createHeader()" also ...
myApp.service('Rest', ['$resource', 'authhandler',
function($resource, 'authhandler',{
return {
User: $resource( api_domain + "/api/users/:userid", {}, {
get: {method: 'GET', headers: authhandler.createHeader()},
remove: {method: 'DELETE', headers: authhandler.createHeader()},
edit: {method: 'PUT', headers: authhandler.createHeader()},
add: {method: 'POST', headers: authhandler.createHeader()},
patch: {method: 'PATCH', headers: authhandler.createHeader()}
}),
};
}]);
Has someone an idea how to solve this ?
I had a working solution but I don't like it because of huge amount of copy and paste source code:
myApp.controller('MyController', function(RestResource, authhandler, $routeParams) {
$http.defaults.headers.common = authhandler.createHeader();
RestResource.get({userid: $routeParams.id}, function(result) {
//...
});
});
I Would be very happy about hints how to solve this ! Thanks in advance!
You can use a request transformer:
function($resource, 'authhandler',{
return {
User: $resource( api_domain + "/api/users/:userid", {}, {
get: {
method: 'GET',
transformRequest: function(data, headersGetter) {
var currentHeaders = headersGetter();
angular.extend(currentHeaders, authhandler.createHeader());
return data;
}
},
You could also add the transformer to all requests:
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.transformRequest.push(function(data, headersGetter) {
var currentHeaders = headersGetter();
angular.extend(currentHeaders, authhandler.createHeader());
return data;
});
That way you don't have to configure anything or your resources.
I'm implementing my own API-Token system into my AngularJS-Laravel project, so the API-Token is sent over $http using headers. The thing is, when a user logs in, it sets the API token in the API factory, but the $resource doesn't get updated.
myApp.factory('Api', ['$resource', '$http', '$cookies',function($resource, $http, $cookies) {
var baseURL = 'an api url';
var APIToken = $cookies.token;
return {
SetToken: function(token) {
APIToken = token;
console.log(APIToken);
},
Authenticator: function(data,callback) {
$http({
url: baseURL + 'auth',
method: "GET",
params: data
}).success(callback);
},
Authors: $resource(baseURL + "journalists/:id", {id: '#id'}, {
update: {
method:'PUT',
headers: { 'API-Token': APIToken }
},
query: {
method:'GET',
isArray: true,
headers: { 'API-Token': APIToken }
}
}),
};
}]);
The most interesting part is the headers: { 'API-Token': APIToken } part. The problem is that when SetToken is called, the headers won't get updated. Is there any way around this? Am I using the wrong function for this?
Your $resource object is created and setup only once when it is called. It doesn't access the APIToken variable every time you make a call to one of its functions. In order to make the code above work, you would have to call SetToken() before you call Authors() because once you call Authors(), the $resource object is created and will use the value of APIToken at that moment. I don't know of any way to do what you want and still use the $resource service. You might have to just use the $http service directly, like you're doing for your Authenticator function.
Authors: {
update: function(obj){
$http({
url: baseURL + 'journalists/' + obj.id,
method: "PUT",
params: obj
});
},
query: function(obj){
$http({
url: baseURL + 'journalists/' + obj.id,
method: "GET",
params: obj
});
},
})
Or something like that. Hope that helps.