API invoked failed: Custom headers present ; using Angular $http.get - javascript

(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,

Related

Convert JS Post Ajax to AngularJS Post Factory

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();
}]);

javascript injection $http post method does not work

so I am creating Google Chrome Extension and at first I was injecting my html, angular and javascripts via content script. No I need to inject it by my own. I made that! But the problem is that when it was injected via content script my login method worked just fine in return I got token (that's what I needed), but when injected by myself my login function does not work anymore and it throws this error:
XMLHttpRequest cannot load http://www.cheapwatcher.com/api/Authenticate. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://anywebsitename.com' is therefore not allowed access. The response had HTTP status code 400.
This is my login method (I haven't changed anything since changed the injection type):
angular.module('app').controller('LoginController', LoginController);
LoginController.$inject = ['$scope', '$http', '$location', '$state'];
function LoginController($scope, $http, $location, $state) {
$scope.login = function (user) {
user.grant_type = 'password';
return $http({
method: 'POST',
url: 'http://www.cheapwatcher.com/api/Authenticate',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Access-Control-Allow-Origin': '*'
},
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: user
}).success(function (result) {
console.log(result);
$(".cheap-watcher").fadeOut(1500, function () {
$(".cheap-watcher").fadeIn($state.go("logout"), {}, { location: false }).delay(2000);
})
}).error(function (result) {
console.log(result);
});
};
};
Can I do something without making CORS on server side? Because as I said injecting via content script works just fine
UPDATE!
So I changed my login method from $http to $.ajax. Everything is the same just instead of $http I wrote $.ajax and removed headers section. In chrome source control the error is the same, but now in fiddler I can see that my request was successful. How is that possible?
now login method looks like this:
angular.module('app').controller('LoginController', LoginController);
LoginController.$inject = ['$scope', '$http', '$location', '$state'];
function LoginController($scope, $http, $location, $state) {
$scope.login = function (user) {
user.grant_type = 'password';
return $.ajax({
url: "http://www.cheapwatcher.com/api/Authenticate",
crossDomain: true,
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
method: 'POST',
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: user
}).success(function (result) {
console.log(result);
$(".cheap-watcher").fadeOut(1500, function () {
$(".cheap-watcher").fadeIn($state.go("logout"), {}, { location: false }).delay(2000);
})
}).error(function (result) {
console.log(result);
});
};
};
UPDATE NR. 2!
I saw that error is coming from http://anywebsitename.com 's index page. So I assume that my login request is running not from my extension but from website content. Are there any communication possible from injected script to background script?
Take a look at Requesting cross-origin permissions, you can add http://www.cheapwatcher.com/api/Authenticate to permissions sections.
By adding hosts or host match patterns (or both) to the permissions section of the manifest file, the extension can request access to remote servers outside of its origin.
To use CORS within Angular, we need to tell Angular that we’re using CORS. We use the
.config() method on our Angular app module to set two options.
We need to tell Angular to use the XDomain and
We must remove the X-Requested-With header from all of our requests
angular.module('myApp')
.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers
.common['X-Requested-With'];
});

Error -1 send parameters using $http.post angular

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.)

Angular $http service / controller to JSONP

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]'
}
});

How to send a custom header on every request with an angular resource?

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.

Categories

Resources