Im having trouble making REST API calls in my ionic app to my server. It shows the following error.
ionic.bundle.js:25005 OPTIONS https://website.com/api/ionic_test 406 (Not Acceptable)
XMLHttpRequest cannot load https://website.com/api/ionic_test. Response for preflight has invalid HTTP status code 406
API call code.
$http.post(API_ENDPOINT.url + '/ionic_test', user).then(function(result) {
if (result.data.status) {
storeUserCredentials(result.data.token);
resolve(result.data.msg);
} else {
reject(result.data.msg);
}
});
ionic.config.json
{
"name": "adminPanel",
"app_id": "",
"proxies": [
{
"path": "/api",
"proxyUrl": "http://website.com/api"
}
]
}
The problem is with your server. In the comments you said the API works in browser, but not in your app. That's because your browser doesn't send an OPTIONS "preflight" request, which Ionic does.
You need to either disable the preflight request, or configure your server to handle it properly.
Use these in your app config to resolve the preflight issue
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
Eg.
angular.module('yourApp', [])
.config(function ($stateProvider, $httpProvider, $urlRouterProvider) {
//To solve Response for preflight has invalid HTTP
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
//--------------------------------------
// your routes here
});
Related
I am having an $http request in my localhost which is calling a url of some api. I am getting an error on executing the call
Response for preflight has invalid HTTP status code 403
Can I do anything using angular so that I can fix this issue? I have CROS plugin of chrome to allow cross origin request
$http({
method: 'POST',
url: url,
data:data1,
headers: {
'Access-Control-Allow-Origin': '*',
}
})
If you using java restful controller as your server.
You can refer to https://spring.io/guides/gs/rest-service-cors/
I added #CrossOrigin(origins = "*") on my controller and it works.
Basically, you cannot do anything in the client side.
Lin
Ok so here's how I figured this out. It all has to do with CORS policy. Before the POST request, Chrome was doing a preflight OPTIONS request, which should be handled and acknowledged by the server prior to the actual request. Now this is really not what I wanted for such a simple server. Hence, resetting the headers client side prevents the preflight:
app.config(function ($httpProvider) {
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
});
The browser will now send a POST directly. Hope this helps a lot of folks out there... My real problem was not understanding CORS enough.
Link to a great explanation: http://www.html5rocks.com/en/tutorials/cors/
Kudos to this answer for showing me the way.
AngularJS POST Fails: Response for preflight has invalid HTTP status code 404
I have this code in angularjs:
$http.post('http://localhost:8080/employee/'
, $scope.alumno
,{headers: {'Content-Type': 'application/json'}}
).success(function(data){
if ( data.err === false ) {
$scope.actualizado = true;
setTimeout(function() {
$scope.actualizado = false;
$scope.$apply();
}, 3500);
};
});
My API have this data:
//Add employee:
Url: http://localhost:8080/employee
Type request: POST
Add a new employee:
{
"firstName": "Javier",
"lastName": "Piedra",
}`
I use chrone with extension for available CORS for the GET all perfect but post sample this error:
XMLHttpRequest cannot load http://localhost:8080/employee/. Response for
preflight has invalid HTTP status code 403
In my app.config use:
app.config( function($routeProvider,$httpProvider){
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
Maybe this can be a solution for your issue.
Regards
Below is my service call where I am trying to do a basic auth. I have checked multiple blogs could not find the solution for this.
Can anybody help me to solve this issue as I am getting below error:
XMLHttpRequest cannot load
Response for preflight has invalid HTTP status code 401
I could not find the basic auth in the network tab in developer options also.
function() {
"use strict";
var APIservice = function($http, $base64) {
var getDetails = function(postData) {
$http.defaults.headers.common['Access-Control-Allow-Origin'] = "*";
$http.defaults.headers.common['Access-Control-Allow-Methods'] = "GET,PUT,POST,DELETE,OPTIONS";
$http.defaults.headers.common['Access-Control-Allow-Headers'] = "Content-Type, Authorization, Content-Length, X-Requested-With";
$http.defaults.headers.common['Content-Type'] = undefined;
console.log($http.defaults.headers.common.Authorization);
//console.log($http.defaults.headers.common.Authorization);
return $http.get('http://52.74.68.202:8080/rest/v1/step/all')
.then(function(response, headers, config) {
console.log(response);
return response;
});
};
return {
getDetails: getDetails
}
}
var module = angular.module('expframework');
module.factory("APIservice", APIservice);
module.run(['$http', '$base64', function($http, $base64) {
var authdata = $base64.encode('test:test');
$http.defaults.headers.common['Authorization'] = 'Basic ' + authdata;
}]);
module.config(['$httpProvider', '$base64', function($httpProvider, $base64) {
var authdata = $base64.encode('test:test');
$httpProvider.defaults.headers.common['Authorization'] = 'Basic ' + authdata;
}])
}();
It is working in Safari and emulators but not working in Chrome and Firefox
Please help me to fix this. Thanks in advance.
Since your server threw a 401, I guess it tried to authenticate the preflight request. From https://stackoverflow.com/a/15734032/1225328:
The W3 spec for CORS preflight requests clearly states that user credentials should be excluded.
[...]
Simply have the server (API in this example) respond to OPTIONS requests without requiring authentication.
I am using angularjs, In backend I check every api authenticated.
Every request should be checked the parameter access_token.
$provide.factory('MyHttpInterceptor', function($q, $location, $localStorage) {
return {
request : function(config) {
config.params = config.params || {};
if ($localStorage.access_token) {
config.params.access_token = $localStorage.access_token;
}
return config || $q.when(config);
},
};
});
// Add the interceptor to the $httpProvider.
$httpProvider.interceptors.push('MyHttpInterceptor');
I using this code. Its working good, but I saw in development tools(Network) the html, css, js files also added the parameters.
like.
http://localhost/webapp/views/template/left-menu.html?access_token=xxxxxxxxxxxxxxxxx
http://localhost/webapp/css/index.css?access_token=xxxxxxxxxxxxxxxxx
But I don't like to send access_token to all http request(html,css,js).
I like to send the access_token for what are have prefix api
http://localhost:9090/api/user/get?access_token=xxxxxxxxxxxxxxxxxxxxxx
//I think the solution is find the http url and grep the text api, if found means add the parameter. Don't konw this is good approach.
Please me the good approach.
I expect only backend api request only.
Also I don't expect every serive http request to add parameter.
Its possible to add common one place in config ?
You can check url:
$provide.factory('MyHttpInterceptor', function($q, $location, $localStorage) {
return {
request : function(config) {
var apiPattern = /\/api\//;
config.params = config.params || {};
if ($localStorage.access_token && apiPattern.test(config.url)) {
config.params.access_token = $localStorage.access_token;
}
return config || $q.when(config);
}
};
});
// Add the interceptor to the $httpProvider.
$httpProvider.interceptors.push('MyHttpInterceptor');
Using Angular, I'm trying to pass in HTTP headers with the request, “App-Id” and “App-Key” to get data from this API.
I tried setting the headers like this:
$http.defaults.headers.common["App-Id"] = '5a3d8b8d';
$http.defaults.headers.common["App-Key"] = '738e9aca62e7465446b7be8fe4219ffa';
but I got a Response for preflight is invalid error.
http://jsfiddle.net/9Ymvt/4573/
Adding Headers to an $http Request on a Per Request Basis
To add headers to a $http request on a per request basis, add them to the headers property of the $http config object.
var xheaders = {};
xheaders["App-Id"] = '5a3d8b8d';
xheaders["App-Key"] = '738e9aca62e7465446b7be8fe4219ffa';
var xurl = 'https://uk.bookingbug.com/api/v1';
var configObj = { method: 'GET',
url: xurl,
headers: xheaders
};
$http(configObj)
.then(function onFulfilled(response) {
console.log(response);
vm.headers = response.config.headers;
vm.data = response.data
}).catch( function onRejection(errorResponse) {
console.log("Error: ", errorResponse.status);
console.log(errorResponse);
vm.error = errorResponse;
})
;
The code was getting pre-flight errors because it was using the incorrect URL. The correct base URL is https://uk.bookingbug.com/api/v1 which supports App-Id headers and CORS.
The DEMO on JSFiddle.
I do not think this is a complete answer to your question, but here is what I have in my project:
var app = angular.module('app', ['ngRoute']);
app.config(function($routeProvider) {
// code for routes
});
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);
This solves my problem with CORS. If you want to do another type of header, you probably can find your answer here.
Preflight errors are related to CORS. You might want to look at rack-cors to enable cross-site api calls via javascript. There is a manual configuration here: https://gist.github.com/dhoelzgen/cd7126b8652229d32eb4
I wrote this in AngularJS service block and I can't get it to work properly:
app.factory('sfAttachment', ['$http', '$q', '$window', function($http, $q, $window){
var attachment = {};
//Save to server function for attachments
attachment.save = function( base64value, mimeType, currentDocTypeId, currentFilename, attachmentId ){
var data = {
"Body" : base64value,
"ContentType": mimeType,
"ParentId": currentDocTypeId,
"Name": currentFilename
};
var url = $window.__url;
var method;
var isUpdate = ($.trim(attachmentId) !== '');
if (isUpdate) {
url = url + attachmentId;
method = 'PATCH';
} else {
// Method for creation
method = 'POST';
};
var request = {
url: url,
method: method,
data: data
};
var deferred = $q.defer();
$http(request).then(function(response){
deferred.resolve(response);
console.log('file SAVED');
console.log(response);
}, function(event){
deferred.reject('The attachment could not be saved:' + event);
});
return deferred.promise;
}
return attachment;}]);
app.run(['$http','$window',function ($http, $window) {
var sessionId = $window.__sfdcSessionId;
$http.defaults.useXDomain = true;
delete $http.defaults.headers.common["X-Requested-With"];
$http.defaults.headers.common["Access-Control-Allow-Origin"] = "*";
$http.defaults.headers.common["Accept"] = "application/json";
$http.defaults.headers.common["content-type"] = "application/json";
$http.defaults.headers.common['Authorization'] = "OAuth " + sessionId ;
$http.defaults.headers.common['X-User-Agent'] = "MyClient" ;
}]) ;
I keep getting these errors:
Failed to load resource: the server responded with a status of 400 (Bad Request)
As well as this:
MLHttpRequest cannot load https://youri.cs22.my.salesforce.com/services/data/v26.0/sobjects/Attachment/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://youri--c.cs22.visual.force.com' is therefore not allowed access. The response had HTTP status code 400.
I added https://youri--c.cs22.visual.force.comto the remote Site settings in Salesforce but that still seem to be causing issues...
Any suggestions?
EDIT: I figured out the first part of my issue I needed to white list https://youri--c.cs22.visual.force.comin Remote Settings> CORS and not remote sites but I still get the Bad request error...
See the Edit:
EDIT: I figured out the first part of my issue I needed to white list https://youri--c.cs22.visual.force.comin Remote Settings> CORS and not remote sites but I still get the Bad request error...