Angular JS - can't receive any response using $http.post - javascript

I'm trying to get a response from a web service using Angular JS, which I can perfectly reach via my shell using a simple curl command:
curl --header "Content-type: application/json" --request POST
--data '{"username": "name", "password": "pwd"}' 192.168.2.1:9000/ws/login
However, when I try to reach it using Angular with an $http.post I experience some "funny" behaviour.
While my data are:
var url = "192.168.2.1:9000/ws/login"
var postData = {
username: un,
password: pwd
}
I've tried both postData as a JSON object and as a stringified JSON
Using a call like this:
$http.post( url, postData ).
success(function(data) {
console.log(data)
}).
error(function(data, status, headers, config) {
console.log(data, status, headers, config)
})
or even
$http({
url: url,
method: 'POST',
data: JSON.stringify(postData),
headers: {'Content-type': 'application/json'}
}).
success(function(data, status, headers, config) {
console.log('Success: ', data, status, headers, config)
}).
error(function(data, status, headers, config) {
console.log('Error: ', data, status, headers, config)
})
Simply do nothing.
Nothing at all!
Prepending an http:// to the url instead, gives me:
OPTIONS http://192.168.2.1:9000/ws/login 404 (Not Found) angular.js:7073
OPTIONS http://192.168.2.1:9000/ws/login Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.
I'm really really lost... any advice would be much appreciated!

I've managed to get a CORS setup up & running.
The server side for my case was far from trivial, since we're using Play! framework and modern browsers sends an OPTION method before sending the real POST method, to be somewhat "pre-authorized" to send the CORS request.
As stated in http://better-inter.net/enabling-cors-in-angular-js/ I had to add
$http.defaults.useXDomain = true;
prior of the actual $http.post, but I didn't had to delete the 'Content-Type' header
Should you ever use a similar setup, I would reccomend taking a look on these resources:
Play 2.0.1 and setting Access-Control-Allow-Origin
Play! 2.0 easy fix to OPTIONS response for router catch-all?

As Adam said!
If you are using apache:
Header set Access-Control-Allow-Origin: http://domain.com, http://localhost/
or just
Header set Access-Control-Allow-Origin: *
Do this only for testing. For production limit the origin to only your domain.

Related

google invisible reCaptcha server side validation is failing

i have integrated the invisible reCaptcha in my application and the client side response is coming as part of solving the image challenge. i am then calling a angular function to validate user response on server side using below code. where onloginSubmit(token) is the success call back.
<button id="btnLogin" ng-disabled="loginForm.$invalid"
class="g-recaptcha primarybtn margin-left-zero form-control-input"
data-sitekey="{{public_key}}"
data-callback='onloginSubmit'>{{'label_login' |
translate}}</button>
<script>
function onloginSubmit(token) {
angular.element(document.getElementById('loginForm')).scope().verifyReCaptcha(token);
};
</script>
in angular i am calling the verifyReCaptcha as below.
$scope.public_key = "------ My Site Key -------";
$scope.private_key = "------ My Secret Key -------";
$scope.verifyReCaptchaURL = "https://www.google.com/recaptcha/api/siteverify";
$scope.verifyReCaptcha = function(reCaptchaToken){
var captchaData = {
secret : $scope.private_key,
response : reCaptchaToken
}
$http({
headers: {
'Accept': 'application/json,text/plain',
'Content-Type': 'application/json;application/x-www-form-urlencoded;charset=utf-8;',
},
url: $scope.verifyReCaptchaURL,
method: 'POST',
data: captchaData
}).success(function (data) {
console.log("success");
$scope.login();
}).error(function (data) {
console.log("error");
$window.location.reload(true);
});
};
when i hit the api service https://www.google.com/recaptcha/api/siteverify . i get the below error.
Failed to load https://www.google.com/recaptcha/api/siteverify: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 405.
i couldnt find more documentation for the issue.
what is it that i am doing wrong and also if there is any error the recaptcha does not come up and the login button which i am using fails to respond.
n the request i am mentioning the Method as Post, the method is over ridden as Options and the request payload which i am sending is not present. this is what i got in the networks tab
Request URL:https://www.google.com/recaptcha/api/siteverify
Request Method:OPTIONS
Status Code:405
Remote Address:10.120.118.50:8080
Referrer Policy:no-referrer-when-downgrade
Most of the thing you did a great job. One thing is to require in your application is communicate to an external domain so you can include HTTP header content type is include a JSONP format.
$http({
headers: {
'Accept': 'application/json,text/plain',
'Content-Type': 'application/jsonp;application/x-www-form-urlencoded;charset=utf-8;',
},
url: $scope.verifyReCaptchaURL,
method: 'POST',
data: captchaData
}).success(function (data) {
console.log("success");
$scope.login();
}).error(function (data) {
console.log("error");
$window.location.reload(true);
});

AngularJS Refused to set unsafe header "Cookie"

I am using an AngularJS application to make a call to an API using $http. The call to $http is originating from localhost:9000. The API is endpoint is available at localhost:9100/API/v1.0/context...
I am getting an error message saying "Refused to set header Cookie". From what I have read, the browser sets these headers for security reasons and these cannot be configured. According to the similar question heresimilar question here, I have tried enabling crossDomain:true and withCredentials:true but to no effect.
Any answer on why this is happening would be appreciated.
EDIT: Here is the code
$http({
method: method,
url: urlpoint,
headers:headers,
params: query,
crossDomain: true
})
.success(function(data, status, headers, config) {
if (!data || data.length == 0)
data = $rootScope.getLocaleValue("EMPTY_RESPONSE");
operation.result.data = data;
$scope._afterMakeTestCall(operation, status,
headers, config);
});
And in the headers field, I have set
headers['Cookie'] = 'cookieValue="something";';
After a long time of searching, I came across references stating that browser will not allow to set the Cookie header due to security vulnerabilities. It can only be done through headless browsers.

angularJS sending OPTIONS instead of POST

Im stuck at this 2 days I can not find a solution.
When im doing an AngularJS POST it Sends OPTIONS in the header and returns error from the API the code looks like this nothing special.
$http.defaults.headers.post["Content-Type"] = "application/json";
$http.post(URL, JSON.stringify(data)).
success(function(data, status, headers, config) {
alert(data);
error(function(data, status, headers, config) {
console.log("Error");
});
CORS is enabled on the API it has the Headers, when i do POST with fiddler or POSTMan in Chrome it works fine only when i use angularJS post it won't go thru.
why do i get OPTIONS /SubmitTicket HTTP/1.1 instead of POST?
What do i need to do to POST ? I have read about it it says something like CORS is adding OPTIONS header but why?
When you invoke the CORS requests, the browser always sends the OPTIONS request to server to know what methods are actually allowed. So this is the desired behaviour. This is so called: "Preflighted request", see: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/ (section: "Preflighted requests")
Therefore in your case, you have to allow the OPTIONS method in 'Access-Control-Allow-Methods' header of your CORS filter.
My understanding is that angular initially sends an OPTIONS request to the server in order to ask the server if the full request is permissable.
The server will then respond with Headers specifying what is and is not allowed.
I guess this might be an issue with the server returning the wrong CORS headers.
You said that the server returns an error please post that error here.
See Preflighted CORS request at: http://www.staticapps.org/articles/cross-domain-requests-with-cors
and
AngularJS performs an OPTIONS HTTP request for a cross-origin resource
// Simple POST request example (passing data) :
$http.post('/someUrl', {msg:'hello word!'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Should only need to do this code to get it to work:
angular.module('TestApp', [])
.factory('someService', ['$http', someService]);
function someService() {
var service = {
save: save
};
var serviceUrl = '/some/Url';
return service;
function save(data) {
$http.post(serviceUrl, data)
.success(function(data, status, headers, config) {
alert(data);
})
.error(function(data, status, headers, config) {
console.log("Error");
});
}
}
Then pull your someService into your controller and use:
someService.save(data);

CouchDB XMLHttpRequest Error

I am using Angular to connect to a server running CouchDB that I have set-up. When ever I run the code I get the error:
"XMLHttpRequest cannot load http://ip:5984/_all_dbs. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://morris-tibet.codio.io' is therefore not allowed access."
I have set-up the origins and cannot understand what the problem could be.
Here is the code I am using to connect:
myApp.controller('OverviewCtrl', ['$http',
function($http) {
var self = this;
self.dbNames = [];
$http({
url: 'http://ip:5984/_all_dbs',
method: 'GET'
}).
success(function(data, status, headers, config) {
self.dbNames = data;
console.log(self.dbNames);
}).
error(function(data, status, headers, config) {
self.dbNames = ['Something wrong with your code!', ''];
console.log(self.dbNames);
})
}
]);
In the code the ip address has been replaced for security reasons.
EDIT:
I was told it may be an issue with my CORS, here is an image showing my cors for the server:

AngularJS: Cannot send POST request with appropiate CORS headers

I'm creating a web app using AngularJS. To test it, I'm running the app in a NodeJS server, using angular-seed template.
In this app, I need to send a JSON message to another host, via POST request, and get the response, so, I'm using CORS.
My request is done by implementing a service that uses AngularJS http service (I need the level of abstraction that $http provides. So, I don't use $resource).
Here, my code. Please pay attention to the fact that I modify $httpProvider to tell AngularJS to send its requests with the appropriate CORS headers.
angular.module('myapp.services', []).
// Enable AngularJS to send its requests with the appropriate CORS headers
// globally for the whole app:
config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
/**
* Just setting useXDomain to true is not enough. AJAX request are also
* send with the X-Requested-With header, which indicate them as being
* AJAX. Removing the header is necessary, so the server is not
* rejecting the incoming request.
**/
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]).
factory('myService', function($http) {
return {
getResponse: function() {
var exampleCommand = JSON.stringify({"foo": "bar"});
// This really doesn't make a difference
/*
var config = {headers: {
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Headers': 'Content-Type, Content-Length, Accept',
'Content-Type': 'application/json'
}
};
*/
//return $http.post(REMOTE_HOST, exampleCommand, config).
return $http.post(REMOTE_HOST, exampleCommand).
success(function(data, status, headers, config) {
console.log(data);
return data;
}).
error(function (data, status, headers, config) {
return {'error': status};
});
}
}
});
The problem is I can't make it work. I always get this error message:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at REMOTE_HOST. This can be fixed by moving the
resource to the same domain or enabling CORS.
But if I do a simple jQuery AJAX call like this:
$.ajax(REMOTE_HOST,
{
dataType: "json",
type: "POST",
data: exampleCommand,
success: function(data) { console.log(data); },
error: function(request, textStatus, errorThrown) { console.log("error " + textStatus + ": " + errorThrown);}
});
It works fine.
So, my questions:
- How do I allow cross-site requests in an AngularJS running under NodeJS?
UPDATE: Thanks to Dayan Moreno Leon's response.
My problem is I need to add cors support to my server. I'm using NodeJS http-server for development and lighttpd for production.
- Why does the simple jQuery POST request work but AngularJS POST request doesn't?
I guess jQuery AJAX requests are cross-domain by default. Not really sure yet.
Many thanks in advance
CORS is not handled on the client but in the server you need to allow CORS on your nodejs app where your angular app is trying to POST. you can try using cors module if you are using express
https://www.npmjs.org/package/cors
other whise you need to check for the options method and return 200 as a response
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Why does the simple jQuery POST request work but AngularJS POST request doesn't?
jQuery uses simple requests while AngularJS uses preflighted requests
In your angular code you can add set Content-Type to application/x-www-form-urlencoded and encode your data using $.param

Categories

Resources