I have searched everywhere for an answer but nothing have worked so far. All the listed solutions on stack have not proven to be sufficient.
I get nothing in my laravel log in form of errors and I only get the standard:
XMLHttpRequest cannot load http://api.domain.dev/post/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://domain.dev' is therefore not allowed access.
Laravel controller:
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Post;
use App\Tag;
use Illuminate\Http\Request;
class PostController extends Controller {
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$posts = Post::with('user', 'tags')->get();
return response()->json($posts);
}
}
Laravel Routes:
<?php
Route::resource('user', 'UserController');
Route::resource('post', 'PostController');
Route::get('post/tag/{tag}', 'PostController@postsWithTag');
Route::resource('tag', 'TagController');
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
Kind of bloated not organized angular:
//App
var app = angular.module('app', [
'ngRoute',
'ngAnimate'
]);
//Config
app.config(['$routeProvider', '$locationProvider', '$animateProvider', function($routeProvider, $locationProvider, $animateProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
$routeProvider.
when('/', {
templateUrl: 'partials/home.html',
controller: 'PageController'
}).
when('/about', {
templateUrl: 'partials/about.html',
controller: 'AboutController'
}).
when('/contact', {
templateUrl: 'partials/contact.html',
controller: 'ContactController'
}).
when('/blog', {
templateUrl: 'partials/blog.html',
controller: 'PostsController'
}).
when('/blog/post/:postId', {
templateUrl: 'partials/post.html',
controller: 'PostController'
}).
otherwise({
redirectTo: '/'
});
}]);
//Factory
app.factory('Data', function Data($http) {
return {
getPosts: function getPosts() { return $http.get('http://api.domain.dev/post/'); },
getPost: function getPost(id) { return $http.get('http://api.domain.dev/post/' + id); },
addPost: function addPost(data) { return $http.post('http://api.domain.dev/post/', data); },
removePost: function removePost(id) { return $http.delete('http://api.domain.dev/post/'+ id); },
getTags: function getTags() { return $http.get('http://api.domain.dev/tag/'); },
getTag: function getTag(id) { return $http.get('http://api.domain.dev/tag/' + id); },
addTag: function addTag(data) { return $http.post('http://api.domain.dev/tag/', data); },
removeTag: function removeTag(id) { return $http.delete('http://api.domain.dev/tag/'+ id); },
}
});
//Posts Controller
app.controller('PostsController', function PostsController($scope, Data) {
Data.getPosts().success(parsePosts);
function parsePosts(data) {
$scope.posts = data;
}
//AddPost
$scope.newPost = { title: '', content: '', resume: '' };
$scope.addPost = function addPost(){Data.addPost({ title: $scope.newPost.title, content: $scope.newPost.content, resume: $scope.newPost.resume, user_id: $scope.newPost.user_id }).success(postAddSuccess).error(postAddError);}
function postAddSuccess(data) {
$scope.error = null;
$scope.posts.push(data);
$scope.newPost = { title: '', content: '', resume: '' };
}
function postAddError(data) {
$scope.error = data;
}
//RemovePost
$scope.removePost = function removePost(id) {
if (confirm('Do you really want to remove this post?')) {
Data.removePost(id).success(postRemoveSuccess);
}
}
function postRemoveSuccess(data) {
var i = $scope.posts.length;
while (i--) {
if ($scope.posts[i].id == data) {
$scope.post.splice(i, 1);
}
}
}
});
//Post Controller
app.controller('PostController', function PostController($scope, $routeParams, Data) {
Data.getPost($routeParams.id).success(parsePost);
function parsePost(data) {
$scope.post = data;
}
Data.getTags($routeParams.id).success(parsePostsTags);
function parsePostsTags(data) {
$scope.tags = data;
}
$scope.newTag = { tag: '' };
$scope.addTag = function addTag() {
$scope.newTag.post_id = $scope.post.id;
Data.addTag($scope.newTag).success(tagAddSuccess).error(tagAddError);
}
function tagAddSuccess(data) {
$scope.error = null;
$scope.tags.push(data);
$scope.newTag = { tag: '' };
}
function tagAddError(data) {
$scope.error = data;
}
$scope.removeTag = function removeTag(id) {
if (confirm('Do you really want to remove this tag?')) {
Data.removeTag(id).success(tagRemoveSuccess);
}
}
function tagRemoveSuccess(data) {
var i = $scope.tags.length;
while (i--) {
if ($scope.tags[i].id == data) {
$scope.tags.splice(i, 1);
}
}
}
});
//About Controller
app.controller('AboutController', function AboutController($scope, Data) {
});
//Portfolio Controller
app.controller('PortfolioController', function PortfolioController($scope, Data) {
});
//Contact Controller
app.controller('ContactController', function ContactController($scope, Data) {
});
//Page Controller
app.controller('PageController', function PageController($scope, Data) {
});
I have no clue where to go from here.
I have tried everything from the normal header()
implementation to using laravel-cors package to implement via filters and the _construct in the controller.
I have also gone the server config route and tried adding the header to the .htaccess and the virtualhost config.
I don't have good knowledge in laravel.but My suggestion is to the request headers to access REST Methods(GET,POST,PUT,DELTE) and origin to specific domain from which domain your making request in the following way or else set to '*'(it allows any domain)
At angular js.If you use <1.2 you can set CORS in controller file like following way.In latest version not required it will set default.you need to set what content type your expecting from server default is json.If your expecting other type of content you can set manually in the request.
what i have done but not sure if that is the best solution but there are no cors with that one
1.build the angular normally using
ng build --prod
2.move the content of
angular/dist
tolaravel/public
3.then use this simple code in
laravel/routes/web.php
now all requests comes to Laravel and if it can catch the request with a route this route will work otherwise it will pass it to angular
I had the same problem, but with jQuery and took me weeks to get a good solution.
I my case create an middleware to set headers was the perfect solution.
Create a Cors middleware: App\Http\Middleware\Cors.php
Remember to set Cors alias inside App\Http\Kernel
Inside Routes you can use middleware with group or direct to an specific route, in e.g.:
If someone have this problem with jQuery, I recommend to use $.ajax, instead of $.get, $.post. When you use this methods, jQuery send data using XMLHttpRequest and set content-type to application/x-www-form-urlencoded, it's impossible to change that, so, use Ajax.
e.g.:
Remember: If you are using application/json on request header you must provide "OPTIONS" method, to do a preflight.
More info about CORS: http://www.html5rocks.com/en/tutorials/cors/
When you invoke a cross origin XHR request, javascript first fires an OPTIONS request to the given URL. If this method hasnt added in your routes, then it pops a 404 page which is served without the ACAO header so the concrete POST request wont be sent, as javascript see it not allowed to.
Add these lines in your public/index.php:
See, if that works.
add
to public/index.php if it doesn't work in the function like blue bells suggested