jersey Rest Response in Angular Js - angularjs

I have jersey framework implemented for Rest services version 2.5
I have implemented Get, it works fine and response shows as JSON object in url when I have tried.
When I have tried the same url in angular JS using http.post and $ resource, success comes as 200k but there is no response.
web app deployed in local on glassfish server and jersey rest services deployed in websphere 7
Rest controller
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/{id}")
public Response assignAppointment(#PathParam("id") String id) {
Appointment app = new Appointment();
app.setId(id);
app.setTechName("fffff");
// return Response.status(200).entity(app).build();
return Response.ok(app).build();
}
in Angular JS
$http.get('http://mylocal.com/ntschedulerp/rest/appointment/'+$scope.appt.apptId,
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}}).then(function(appoinmentData)
{
$scope.assignmentForm = "Controller";
$scope.techName=appointmentData.data.techName;
$scope.response1=appointmentData.status;
});
response is empty but status code is 200. but when tried direct url it shows json object i browser. but while accessing from web app, the response is empty..checked in firebug

The issue got resolved. The issue occurred because of the response headers does not accept cross requests.
CORS http request.
Since I have rest server and web app in different servers, angular js does not directly accept the response which does not have specific headers.
To resolve this issue, Both server and client should have headers embedded.
I have resolved as follows
we need add these headers to the response
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods': ['OPTIONS', 'GET', 'POST'],
'Access-Control-Allow-Headers' : 'Content-Type'
On client side, add the magic statement
$http.defaults.useXDomain = true;
before calling $http method in controller, I am using angular js 1.2 version, earlier versions, it might need to do like this..not tested but found some where
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);
on server side, I am using jersey framework (2.5),
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/{id}")
public Response assignAppointment(#PathParam("id") String id) {
Appointment app = new Appointment();
app.setId(id);
app.setTechName("xxxx");
ResponseBuilder response=Response.status(200).entity(app);
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Methods", "Cache-Control, Pragma,
Origin, Authorization, Content-Type, X-Requested-With");
response.header("Access-Control-Allow-Headers", "GET, PUT, OPTIONS,
X-XSRF-TOKEN");
return response.build();
}
one can use,
#Context HttpServletResponse
as method argument in rest methods, if using older versions.

Related

IE Edge Angular JS $http post CORS request JSON not working

I am working on Angular JS app which connects to CORS .NET WEB API. The below code works fine with chrome / firefox / safari browsers but for some reason not on IE Edge (any version). I get OPTIONS pre-flight response with HTTP code 200 but subsequent post request does NOT fire.
var postData = {
'id': 1,
'name':'Niket'
}
function SendData(APIServiceUrl, postData)
{
return $http({
method: 'POST',
url: URL + APIServiceUrl,
data: postData,
headers: { 'Content-Type': 'application/json; charset=UTF-8' }
});
}
If I switch the content-type to
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
then I do get the post request working. But our API Server response only allows
Access-Control-Allow-Headers: Authorization, Content-Type
I have gone through dozens sites to solve this issue, and have tried bunch of solutions ranging from JSON.stringify(), verifying caching is disabled, syntax checking, CORS setup etc. but not able to find solution to why the POST request does NOT fire in IE Edge.
An article that I have found along similar line is this but that has not been SOLVED either --> Post JSON ajax request with cors not working in IE10/Edge.
Angular JS ver 1.5.7, IE Edge version 40.15063.0.0,
PLEASE HELP!!!

Why does Angular send Http Request Method: Options before POST?

I'm using Angular Dart V1 for a front end framework
I am using shelf && shelf router for a backend API
I'm trying to migrate some old get requests to accept Post Data
Old request:
Future fetchRoutes(FlightPostParamsVO params) async {
return _http.get(BASE + 'routes').then(handleRoutes);
}
New Request
Future fetchRoutes(FlightPostParamsVO params) async {
Map post = params.toPostable();
return _http.post(BASE + 'routes', post ).then(handleRoutes);
}
I'm setting the CORS headers in a generic response for all calls as its strictly a JSON API:
Future<Response> makeResponse( json ) async {
var response = new Response.ok( json, headers: {'content-type': 'text/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': "Origin, X-Requested-With, Content-Type, Accept",
'Access-Control-Allow-Methods': "POST, GET, OPTIONS"} );
return response;
}
I get a 404 an the following output:
OPTIONS http://localhost:1234/tickets/routes 404 (Not Found)
(index):1 XMLHttpRequest cannot load http://localhost:1234/tickets/routes. 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 404.
When i inspect the network traffic - all my GET request DO HAVE the correct headers
When i inspect the network traffic - my POST call is lead bya request with a method set as OPTIONS - this call does not have the headers included.
My POST route handler never gets called
Router
Router airRouter = router();
Router tickets = airRouter.child('/tickets');
tickets.add('/cities', ['GET'], controller.handleCitites);
tickets.add('/times', ['GET'], controller.handleTimes);
tickets.add('/routes', ['POST'], controller.handleRoutes);
tickets.add('/{id}/tickets/', ['GET'], controller.handleTickets);
io.serve(airRouter.handler, 'localhost', 1234);
Fix Symptom:
tickets.add('/routes', ['OPTIONS'], controller.handleRoutes);
Question: Why is the HTTP Request sending a Request Method:OPTIONS before each POST, and whats the proper way only call POST?
That is not angular. Its the browser. The first request of method OPTION is to test for CORS header to make sure the browser is allowed to post.
Solution:
http://thomaslockerambling.blogspot.com/2014/10/shelf-middleware-adding-cors-headers.html
Create a CORS Object and append to header
Intercept an Call to OPTIONS
Response with status code 200 OK

AngularJS $http GET method to backend server: Request Method:OPTIONS 405

$http GET request to a clojure backend, to get a list of services.
I get is an OPTIONS request (???), which gets a 405 response...
<code>
var config = {headers: {
'Authorization': 'Bearer d2VudHdvYW5nZV9tZQ',
"X-Testing" : "testing"
}
};
$http.get(SERVER.MESSAGE_SERVICES, config)
.success(function(successCallback) {
$scope.services = successCallback;
})
.error(function(errorCallback) {
console.log(errorCallback.toString);
}).
finally(function() {
console.log("Message services rest call");
});
</code>
**clojure backend**:
<code>
headers {"Access-Control-Allow-Origin" "*"
"Access-Control-Allow-Headers" "X-Requested-With, Origin,Content-Type, Accept"
"Access-Control-Allow-Methods" "GET, POST, OPTIONS"}
</code>
There is no problem that AngularJS sends an OPTIONS request, that is because CORS standards force to do so. Be sure that the server is configured to allow a GET method.
Yes as raso suggested this problem is because of Cross Origin Resource Sharing(CORS). The same old privacy policy prevents JS/ angularJS from making requests across domain boundaries.
Configure server to allow cross domain requests.
Or
If you are using Chrome than you can use this extension to surpass this problem.

AngularJS POST fails with No 'Access-Control-Allow-Origin' when using data payload object but works using query params like payload

I am facing a weird issue. I am running my angularjs app in nodejs server locally which calls a POST API from my app located on Google App Engine. The API is configured with all CORS headers required as follows:
def post(self):
self.response.headers.add_header("Access-Control-Allow-Origin", "*")
self.response.headers.add_header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS")
self.response.headers.add_header("Access-Control-Allow-Headers", "X-Requested-With, content-type, accept, myapp-domain")
self.response.headers["Content-Type"] = “application/json; charset=utf-8”
GET requests to the API work without issues.
POST requests to the API work but ONLY when I send the post data as a 'string of params' and NOT when post data is sent as an object which is the right way to do. Eventually I need to be able to upload pictures using this API so the first solution below might not work for me. Please help!
METHOD 1: This works:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = "conversationid=1c34b4f2&userid=67e80bf6&content='Hello champs! - Web App'";
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz",
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
METHOD 2: This fails:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = ({
'conversationid' : '1c34b4f2',
'userid' : '67e80bf6',
'content' : 'Hello champs! - Web App'
});
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz"
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
When I use METHOD 2 it fails with the following error in the console:
XMLHttpRequest cannot load https://myapp-qa.appspot.com/message.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://0.0.0.0:8000' is therefore not allowed access.
Please let me know if you have any solution. Thanks in advance.
The issue is most likely with Angular sending a pre-flight OPTIONS request to check the access headers from the server. I am not sure how OPTIONS requests are handled in your API, but I am betting these headers are not being added. I suggest installing Fiddler to monitor the actual requests to see what is going on with the headers. You may only be adding them to your POST responses.
See this answer for details on why METHOD 1 may work in this scenario, while METHOD 2 does not.
Here are some more details about pre-flight requests.

CORS workaround in Angular.js $HTTP POST?

Is there a workaround to sending POST request cross-domain via Angular, besides using a proxy? Below request is refused, ie: OPTIONS , net::ERR_CONNECTION_REFUSED It's just form data I want to submit to friend's local server for school project.
$scope.postJSON = function(){
var objJson = angular.toJson($scope.event);
console.log(angular.toJson($scope.event));
delete $http.defaults.headers.common['X-Requested-With'];
$http({
method: 'POST',
url: 'http://friendslocalserver.com',
data: objJson
}).success(function() {
console.log("POST Json object worked!");
}).error(function(){
console.log("POST Json object failed!");
});
}
You don't need to configure AngularJS for CORS. Your friend's server needs to support CORS requests and probably whitelist your domain. This depends heavily on the HTTP server used.

Resources