CORS with Laravel 4 and external Angular - angularjs

I am noob laravel and angular user. I have wrote very simple api a couple of day ago for learning how does work api. Now i am trying to reach it from another location with very simple angular script. This is my internal domain addres that i'm using instead of localhost/../.. : http://3burcak.dev/api/v1/kategori and this is the index method of kategori controller:
public function index()
{
$cat = EmlakKategori::all();
return Response::json(array(
'cat' => $cat->toArray(),
));
}
So, it is very simple.
When i try to reach it via my very simple angular js, i get OPTIONS 404 not found error if i don't use headers for cors. But if i use those headers inside of filters.php i get OPTIONS 500 Internal Server error.
App::before(function($request)
{
if($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
$statusCode = 204;
$headers = [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
'Access-Control-Allow-Credentials' => 'true'
];
return Response::make(null, $statusCode, $headers);});
App::after(function($request, $response)
{
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
$response->headers->set('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Requested-With');
$response->headers->set('Access-Control-Allow-Credentials', 'true');
return $response;
});
Both situation, i see my json data in Response tab of Firebug... Here is the caps;
Screenshot
And here is my very simple angular
function getKat($http, $scope)
{
$http({
method: 'json',
url: 'http://3burcak.dev/api/v1/kategori'
})
.success(function(data){
$scope.items = data.cat;
})
.error(function(data) {
console.log('error');
});
}
I couldn't solve this problem.
Thanks for help.

I have solved,
I changed angular's method from json to GET and finally it works.

Related

Access-Control-Allow-Headers not allowed in preflight even if I added it on server side

I am getting this error while calling APIs.
Before marking as 'duplicate', please read this.
My frontend is in ReactJs and I'm using axios for API requests, backend in Laravel (v5, old project). Each API gives this error: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.
I have already done the following,
Added cors policy to backend server as middleware:
class CORS {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) {
$headers = [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers' => '*',
// I have tried 'Authorization' instead of '*' also
'Content-Type' => 'application/json',
];
if ($request->getMethod() == "OPTIONS") {
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return Response::make('OK', 200, $headers);
}
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS')
->header('Access-Control-Allow-Headers', '*');
}
}
Is there any other way to get rid of the CORS error or am I missing anything here?
Update
Axios sample code as per requested:
axios.interceptors.request.use(function (config) {
// const token = get auth token from cookie/store
config.headers = {
'Authorization': token ? token : ''
};
return config;
});
Axios request:
Axios.get(myUrl)
.then((response) => {
// do something
})
.catch((err) => {
// show error
});

XMLHttpRequest cannot load https://myserver1:8281/myurl/ext. Preflight issue

I know already the same question has been asked for the preflight issue and so many solutions are provided but i tried almost all of them but its not helping me.
I have a rest api written in java(Sprint) and calling it in my js. My service is getting called and its getting success. I my java code i have written the code for the redirection but direction is not happening and i am getting the below error in browser console:
XMLHttpRequest cannot load https://myserver1:8281/myurl/ext. Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains multiple values 'https://myserver2:21242, *', but only one is allowed.
I tried adding 'Access-Control-Allow-Origin':'*' in the header but still facing the issue. Also tried adding the OPTIONS in the allowed methods in the header.
Below is my js code:
$scope.validateToken = function(){
var config = {
headers : {
'ContentType': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'Expires': '-1',
'X-Requested-By': 'test'
},xhrFields: {
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Headers' : 'Origin, X-Requested-With, Content-Type, Accept',
'Access-Control-Allow-Methods' : 'GET,PUT,POST,OPTIONS'
}
};
$http.get($scope.getUrl, {headers:{'token': $scope.ssoLinkData.token}}).success(function(data, status, headers, config){
}).error(function (data, status, header, config) {
$scope.ResponseDetails = "Data: " + data +
"<hr />status: " + status +
"<hr />headers: " + header +
"<hr />config: " + config;
});
Below is my java code:
#GET
#Path("/ext")
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response myMethod() {
return Response.seeOther(getLocation(redirectionUrl)).
header("Access-Control-Allow-Origin", "*").
header("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS").
header("Access-Control-Allow-Headers", "Origin, Content-Type, X-Auth-Token").
status(200).build();
}
I added the header information in my java code after seeing some post related to the issue. But that is also not helping me.
Can some please help me on this? Thanks in advance
Have you tried doing this:
myApp.config(['$httpProvider', function ($httpProvider){
$httpProvider.defaults.headers.post = {}; //to override the $http post service, hence avoiding browsers encapsulation of post over OPTIONS
}]);
This overrides the default POST pre-flight request and adding "OPTIONS" to your API response header should solve this problem.

Angularjs: Why does adding an authorization header cause a -1 status response?

I have a pre-existing angular code that gets data from an API. I'm trying to add an authentication token to the request.
To begin with I tried a simple example
.factory('getDep', [
'$resource', function($resource) {
return $resource('/ContactsDatabaseAPI/deps/:id', { id: '#id' }, {
query: {
method: 'GET',
isArray: false,
headers: {
'Authorization': 'Bearer ' + token
}
},
create: {
method: 'POST'
},
update: {
method: 'PUT'
},
remove: {
method: 'DELETE'
}
});
}
When the GET call is fired, and F12-ing in Chrome, I get an error message of:
angular.js:11821 OPTIONS http://localhost:56057/ContactsDatabaseAPI/deps net::ERR_CONNECTION_RESET
The return status of -1 and no sign of the call making it to the server side.
Without the headers line, it works fine.
If I try the GET call in Postman with the same Authorization value in the header, this also works fine.
I've also tried to add the header in the httpInterceptor and get the same result:
config.headers = config.headers || {};
config.headers.Authorization = 'Bearer ' + authData.token;
Other things I've tried:
A random header name causes the same issue.
I've added 'Content-Type' = 'text/plain; charset=utf-8' as a header. This has no change to the result
I'm using angular 1.5.6
try this (in the controller) :
$http.defaults.headers.common.Authorization = 'Bearer ' + token;
I've solved my issue and thanks to #Mourad-Idrissi for pointing me in the right direction.
The reason it worked before is that there was no Pre-Flight checks before the API was run. When I added the header, this changed the way the client communicated to the API. Now there was a OPTIONS call to the API which was causing the error. As the domain was different, this introduced me to the world of CORS.
By adding the following to my Application_BeginRequest() method in my backend Web API, Pre-flight now passes and my application continues.
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}

Cross Domain Image upload Angular+laravel

I have been struggling with image upload on server. I am using ngFileUpload on front end. But I always get
"Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource"
Angular Code for file Upload :
var uploadFile = function (file) {
if (file) {
if (!file.$error) {
Upload.upload({
url: baseUrl+'upload',
file: file
}).progress(function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
//console.log(evt.total);
}).success(function (data, status, headers, config) {
$timeout(function() {
console.log(data);
console.log(status);
if(status==200)
{
logo_path = data.logo_path;
}
});
});
}
}
};
On Laravel i have configured CORS like this :
public function handle($request, Closure $next)
{
header("Access-Control-Allow-Origin: http://localhost:8001/");
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
];
if($request->getMethod() == "OPTIONS") {
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return Response::make('OK', 200, $headers);
}
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
}
The Normal cross domain POST request works fine. i.e $http.post(). I have tried many different variations of headers on angular but none helps. Also the OPTIONS request returns 200 OK but still preflight response failure message is displayed. Can anyone help me with how to further debug this issue?
Try adding:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Origin, Content-Type');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
in bootstrap/app.php
You may also insert any other header you may need for access control here.

angular POST request not working but GET working fine

I know this has been asked, but I tried a lot of things and could not make this work.
I am making GET and POST request from my angular application to laravel backend api's. I am able to fetch json from get request but my POST request fails for json data type. It works for
x-www-form-urlencoded
but I am unable to extract data as it is in json format.
$http.get('http://api.app.mywebsite.com/users').success(function(data){
$scope.user = data;
});
$scope.addUser = function(user){
console.log($scope.user);
$http({
method: 'POST',
url: 'http://api.app.mywebsite.com/users',
dataType: 'json',
data: $scope.user,
headers: {'Content-Type': 'application/json; charset=utf-8' }
}).then(function(result){
console.log(result);
}, function(error){
console.log(error);
})
}
$scope.user is posted on form submit.
The error I get :-
XMLHttpRequest cannot load http://api.app.mywebsite.com/users.
Response to preflight request doesn't pass access control check:
No 'Access-Control- Allow-Origin' header is present on the
requested resource. Origin 'http://app.mybackend.com' is therefore not allowed access.
My CORS.php middleware in laravel :-
public function handle($request, Closure $next)
{
header("Access-Control-Allow-Origin: *");
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin, X-Requested-With, Accept'
];
if($request->getMethod() == "OPTIONS") {
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return \Response::make('OK', 200, $headers);
}
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
return $next($request);
}
routes.php
Route::group(['middleware' => 'cors'], function()
{
Route::resource('users', 'UserController');
});
Update:
http://let-aurn.github.io/laravel-5-cors/
You need to configure your http server to allow cors
Similar question:
How to enable CORS in AngularJs
And:
AngularJS performs an OPTIONS HTTP request for a cross-origin resource

Resources