angular-seed POST acts differently for each browser - javascript

I'm not sure what is going on with my http post method. From what I was reading, there might be something wrong with my security, but I am not really sure that is the case or how to fix it. Any insight in the right direction would be nice.
I am trying to post to an API and retrieve a response back and return the data. When I run the POST in IE, I get the proper response.
However when I try this in Chrome I get weird results. My POST turns into an OPTIONS method. With a Status Code of 200 OK, but my Response is blank. And when I try to go to the url directly without the POST I get this displayed in the browser:
{"result":false,"error":"Authentication failed: Session authentication failed: No Host Name specified Authentication State: Invalid Login"}
Here is the test.js (controller)
var host = '255.255.255.255';
var creds = {'logintype':'1','host':host,'user':'Administrator','password':'1234','controlid':'ABC999'};
//var obj = JSON.stringify(creds);
angular.module('myApp.test', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/test', {
templateUrl: 'test/test.html',
controller: 'TestCtrl',
resolve: {
friends: ['$http', function($http) {
return $http({url: 'http://192.168.2.164/ISAPI/rip.dll/REST/SESSIONS/',method: 'POST', data: creds })
.success(function (data) {
return data;
})
.error(function () {
return 'Error';
});
}]
}
});
}])
.controller('TestCtrl', ['$scope', 'friends',function($scope,response) {
$scope.response = response;
}]);

Thanks to itsananderson, I was able to resolve my issue. I was happening because Chrome does something called a "preflight" for cross-domain requests. I needed to move the API to be on the same server as the site was being run to avoid cross site scripting.

Related

passing data using AngularJS $http.get method

I'm building an application using the MEAN stack that would make use of data retrieved from an external API. As a measure to hide the API key, I want to make the API request from the server, however I am having problems passing the search term from the Angular front-end to the server.
The code below is part of the Angular controller, which should pass the request to the server with the search term:
myApp.controller('mainController', ['$scope','$http', '$location', function($scope, $http, $location){
$scope.submit = function(){
$location.path('/results');
$http({method: 'GET', url: '/makeSearch', data: {term: $scope.term} });
}
}]);
and then the following server code would parse the request using the body-parser middleware:
app.get('/makeSearch', function(req, res) {
console.log("I received a command!");
console.log(req.body); });
However once I try to pass/submit a search term from the front-end, I get only an empty object on the server console. Any tips on what I'm doing wrong? Any help would be appreciated.
I figured it out! #Rikky made a good point that the body of a http get request (req.body) is always empty. So by logging just the req to the console, I worked out how the search term can be sent using the GET method
Using params instead of data in the request within the AngularJS controller show in the code below:
revApp.controller('mainController', ['$scope','$http', '$location', function($scope, $http, $location){
$scope.submit = function(){
console.log($scope.term);
$location.path('/results');
$http({method: 'GET',
url: '/makeSearch',
params: {term: $scope.term}
});
} }]);
and on the server, logging req.query instead of req.body as shown in the code below:
app.get('/makeSearch', function(req, res) {
console.log("I received a command!");
console.log(req.query); });
Thanks for the help guys!
There are some http basic that you should know first, then you'll know what you are doing, then, you'll know how to do it right:
With HTTP GET method means querying for data, not sending data. Because of that, an HTTP request with GET method will not have body, so
request.body
will always be empty.
If you really want to send some data to the server, using POST is preferred.
If you still want to send data to the server via get, using query string is the best option. You can check it out at this question
If you want to send some data to the server via get method, but you don't want using query string, you can do some hack with http header instead of http body.
Make sure you have a term property in your scope.
myApp.controller('mainController', ['$scope','$http', '$location', function($scope, $http, $location){
$scope.term ='';
$scope.submit = function(){
$location.path('/results');
$http({method: 'GET', url: '/makeSearch', data: {term: $scope.term}
});
}
}]);
Make sure that your UI has an element which is bound to the term property of your scope
<input type="text" ng-model="term" />

Cross Domain Request with AngularJS doesn't work

I need to do a Cross Domain Request using Angular, but I got the error
XMLHttpRequest cannot load http://machine_name_in_my_network:8082/GetAll. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:53379' is therefore not allowed
access. The response had HTTP status code 500.
I saw here a solution sample, but doesn't worked for me.
This is a request from my localhost to a machine in my network and should return a JSON.
Code Snippet
//Controller
function crmContatosCtrl($scope, apiService) {
apiService.get('/GetAll').then(function (data) {
$scope.contatos = data;
});
and then comes to my service
function comWebApi_Service($http, $log) {
return {
get: function (url, data) {
//return $http.jsonp(ApiURL + url)
// .success(function (data) {
// debugger;
// })
// .error(function (data) {
// debugger;
// });
return $http.get(ApiURL + url, data).then(
function (res) {
return res.data;
});
},
angular
.module('app')
.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}])
.service('apiService', comWebApi_Service);
you need to enable cors on server
e.g. to init it globally
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
read more about it here... read section Scope Rules for [EnableCors]
This is missing code on the server side, not in your browser AngularJS code. You do not need either of these lines with recent angularjs builds. These are both based on outdated information (They won't break anything, they are just unnecessary and based on outdated copypasta):
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
Your server code needs to add the necessary CORS headers to its HTTP responses, so ask the maintainer to do so or post server side snippets and we can help with that.

Angular $http request in the controller does not work

I have the following controller. It works all fine (it parses the data and sends them into the view). The only problem I have is that it does not send $http request. Here is the code block of controller (i just send a test $http without any value from the view just to test it works or not, which does not work):
(It's also worth mentioning that I check via browser's console to see if any ajax request is sent or not)
// Controller
LoginApp.controller("RegisterController", function($scope, $http, registerService){
var username = null;
var password = null;
$scope.registerSubmit = function(){
username = $scope.register.username;
password = $scope.register.password;
};
//registerService.CheckUser();
$http.post('server.php', {name : 'something'})
.success(function(data, status, header, config){
return data;
})
.error(function(data, status, header, config){
return data;
}); // end of $http request
});
EDIT: I have edited what #JoshBeam has recommended, passing data to the post(), but it does not change anything.
You need to pass data along with the HTTP request. According to the AngularJS documentation, it is in this format: post(url, data, [config]);
Thus:
$http.post('server.php', /* your data */);

Angular $http.get with dynamic route?

I'm fairly new to angular and I'm trying to understand how to query from a REST API using a scope variable to determine the URI that is being pulled in the get request.
Lets say I'm in my app.controller and it has a service that spits out an array of numbers.. and for the sake of making the code minimal, I'll skip to the important part:
$scope.currentCompanyId = '0001';
$http.get('/api/'+ $scope.currentCompanyId +'/c').
success(function(data, status, headers, config) {
$scope.cData = data;
}).
error(function(data, status, headers, config) {
// log error
});
I know this is cheating because the $http.get is in the controller. I know it needs to be a factory of some kind.. but I have no idea how to pass the $scope.currentCompanyID to the get request and have it return the JSON. Furthermore, if $scope.currentCompanyID were to change to another number, say... '0002'.. how would the $scope.cData change to reflect the new query?
I don't think using $http in your controller is cheating - one reason for putting it into a factory/service is make it reusable. If you are only doing it in one place a service doesn't add much.
That being said, your service can return a function that takes a parameter:
app.factory("service", function($http) {
return {
getCompany: function(companyId) { ...make $http call and return data... }
}
});
then in your controller:
service.getCompany($scope.currentComanyId).then(function(resp) {...})
You should consider using Angular $resource because it handles a lot of your abstractions. Either way, if you want to make a new request based on changes in the scope variable, you can $watch it:
$scope.$watch('currentCompanyId', function() {
if(!$scope.currentCompanyId) return;
$http.get().success(); // replace with whatever mechanism you use to request data
});
Your request wont launch if currentCompanyId change... You need to lauch your request manually .
otherwise, it seem to be correct
Did you look at $resource service? http://docs.angularjs.org/api/ngResource/service/$resource - it is rather convenient way to REST requests, and docs have quite a few examples that should suit you well
About changing $scope.currentCompanyID - it seems that you need to create watch for this case:
scope.$watch('currentCompanyID', function(newValue, oldValue) {
// do your update here, assigning $scope.cData with the value returned
// using your code:
$http.get('/api/'+ $scope.currentCompanyId +'/c').
success(function(data, status, headers, config) {
$scope.cData = data;
}).
error(function(data, status, headers, config) {
// log error
});
});
You simply need to pass the data in when calling your service. In your controller, you would need to include your service as a DI module and address it as so:
window.angular.module('myControllerModule', [])
.controller('myController', ['$scope', 'myHTTPService',
function($scope, myHTTPService){
$scope.currentCompanyId = 1;
$scope.lookupPromise = myHTTPService.get($scope.currentCompanyId);
$scope.lookupPromise.then(function(data){
//things to do when the call is successful
},function(data){
//things to do when the call fails
});
}]);
In your service, you deal with that value like this:
window.angualr.module('myHTTPServiceModule', [])
.factory('myHTTPService', '$http',
function($http){
function callHTTP(url){
return $http.get('/api/' + url + '/c');
}
return {
get: callHTTP
};
});

Trouble changing Content-Type for POST requests with ngResource (1.0.6 and 1.1.4)

First, I know this question has been asked several times. I have tried many posted solutions and nothing is working for me..
Here are a few other places this was asked:
How to specify headers parameter for custom Angular $resource action
How can I post data as form data instead of a request payload?
Setting application wide HTTP headers in AngularJS
https://groups.google.com/forum/#!msg/angular/Mtsf-YdwwWo/P_Ui4t_DiXkJ
The attempts:
var app = angular.module('theApp', ['app.services']);
app
.config(['$httpProvider', function ($httpProvider) {
// Try (1): This doesn't work
$httpProvider.defaults.headers.common['Content-Type'] = 'application/json;charset=utf-8';
// Try (2): This doesn't work either
$httpProvider.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8';
}])
angular.module('app.services', ['ngResource'])
// Resource for Drupal system/connect.post API (via services.module)
.factory('SystemConnect', function($resource, $http) {
// Try (3): There's no way this should work. But what the hell let's try!
$http.defaults.headers.common['Content-Type'] = 'application/json;charset=utf-8';
$http.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8';
return $resource('api/system/connect.json', {}, {
post: {
method: 'POST',
params: { },
isArray: true,
// Try (4): This doesn't work either
headers: { 'Content-Type': 'application/json;charset=utf-8' }
}
});
});
function SomeCtrl($scope, SystemConnect) {
// FAIL, this results in "406 Not Acceptable: Unsupported content type application/xml"
$scope.user = SystemConnect.post();
}
app.controller('SomeCtrl', SomeCtrl);
It sounds like many people have solved this before. Could someone kindly let me know the right way to do this?
PS: Weirdly, when running this code in Firefox, Angular uses 'Content-Type: text/plain' for the POST!?
I remember reading you have to include content in a post for it to accept your header changes.
$scope.user = SystemConnect.post({});

Categories

Resources