2015-03-14 6 views
3

Я искал всюду для ответа, но пока ничего не получилось. Все перечисленные решения в стеке оказались недостаточными.Laravel 5 + AngularJS Cross Domain CORS

я не получаю ничего в моем журнале Laravel в виде ошибок, и я только получаю стандарт:

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 контроллер:

<?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 Маршруты:

<?php 

Route::resource('user', 'UserController'); 
Route::resource('post', 'PostController'); 
Route::get('post/tag/{tag}', '[email protected]'); 
Route::resource('tag', 'TagController'); 

Route::controllers([ 
    'auth' => 'Auth\AuthController', 
    'password' => 'Auth\PasswordController', 
]); 

Kind раздутой неорганической формы:

//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) { 



}); 

У меня нет понятия, куда идти отсюда. Я пробовал все от обычной реализации header() до использования пакета laravel-cors для реализации через фильтры и _construct в контроллере. Я также пошел по пути конфигурации сервера и попытался добавить заголовок в .htaccess и конфигурацию virtualhost.

+0

Вы попробуйте [Laravel-CORS] пакет (https://github.com/barryvdh/laravel-cors) для отправки заголовков Cross-Origin Resource Sharing? – Mirceac21

ответ

4

У меня была та же проблема, но с jQuery и потребовалось несколько недель, чтобы получить хорошее решение.

I Мое случайное создание промежуточного программного обеспечения для установки заголовков было идеальным решением.

Создание промежуточного программного Корс: App \ Http \ Middleware \ Cors.php

namespace App\Http\Middleware; 

use Closure; 

class Cors 
{ 

    /** 
    * Handle an incoming request. 
    * 
    * @param \Illuminate\Http\Request $request 
    * @param \Closure $next 
    * 
    * @return mixed 
    */ 
    public function handle($request, Closure $next) 
    { 
     return $next($request) 
      ->header('Access-Control-Allow-Origin', $_SERVER['HTTP_ORIGIN']) 
      // Depending of your application you can't use '*' 
      // Some security CORS concerns 
      //->header('Access-Control-Allow-Origin', '*') 
      ->header('Access-Control-Allow-Methods', 'POST, OPTIONS') 
      ->header('Access-Control-Allow-Credentials', 'true') 
      ->header('Access-Control-Max-Age', '10000') 
      ->header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With'); 
    } 
} 

Не забудьте установить Корс псевдоним в App \ Http \ Kernel

protected $routeMiddleware = [ 
    ... 
    'cors' => \App\Http\Middleware\Cors::class, 
]; 

Внутренние маршруты вы можете использовать промежуточное программное обеспечение с группы или непосредственно по конкретному маршруту, например:

Route::match(['post', 'options'], 'api/...', 'Api\[email protected]')->middleware('cors'); 

Если у кого-то есть эта проблема с jQuery, я рекомендую использовать $ .ajax вместо $ .get, $ .post. Когда вы используете эти методы, jQuery отправляет данные с использованием XMLHttpRequest и задает тип контента в application/x-www-form-urlencoded, это невозможно изменить, поэтому используйте Ajax.

.: например

 $.ajax({ 
      type: 'POST', 
      url: 'www.foo.bar/api', 
      contentType: "application/json", 
      xhrFields: { 
       // The 'xhrFields' property sets additional fields on the XMLHttpRequest. 
       // This can be used to set the 'withCredentials' property. 
       // Set the value to 'true' if you'd like to pass cookies to the server. 
       // If this is enabled, your server must respond with the header 
       // 'Access-Control-Allow-Credentials: true'. 
       withCredentials: true 

      }, 

      headers: { 
       // Set any custom headers here. 
       // If you set any non-simple headers, your server must include these 
       // headers in the 'Access-Control-Allow-Headers' response header. 
       'Accept': 'application/json' 
      }, 



      data: '{"some":"json data"}', 
      success: function (data) { 
       console.log('AJAX version'); 
       console.log("Works!") 
      }, 
     }); 

Помните: Если вы используете приложения/JSON в заголовке запроса вы должны предоставить «OPTIONS» метод, чтобы сделать предполетный.

Более подробная информация о CORS: http://www.html5rocks.com/en/tutorials/cors/

+0

Еще одна вещь. Если в вашем контроллере вы возвращаете новый ответ, 'Resnpose :: json()', 'Response :: make()' и т. Д., Вам нужно снова установить заголовки (третий аргумент), потому что заголовки, установленные промежуточным программным обеспечением, не проходят к новому экземпляру Response. –

3

Добавьте эту строку перед возвращением header("Access-Control-Allow-Origin: *");

Ваш код должен быть

public function index() 
{ 
    $posts = Post::with('user', 'tags')->get(); 
    header("Access-Control-Allow-Origin: *"); 
    return response()->json($posts); 
} 
+0

Я вижу, что вы получаете, но ничего не делает, но возвращает ту же ошибку в хром-консоли. – user2298680

+0

@ user2298680 У меня была такая же проблема. Но я решил проблему по заголовку («Access-Control-Allow-Origin: *»); ... Позволяет увидеть, что кто-то решит вашу проблему. –

+0

My Laravel 5.0 API проигрывает сессию, когда приложения angular.js делают логин из другого домена. Эти приложения angular.js размещаются в других доменах, других серверах. – Maykonn

0

Я не имею хорошие знания в laravel.but Мое предложение заключается в заголовках запроса доступа к методам REST (GET, POST, PUT, DELTE) и происхождения для конкретного домена из домена, который ваш запрос решений следующим образом или же установить на «*» (это позволяет любой домен)

header('Access-Control-Allow-Origin', 'some url'); 
header('Allow', 'GET, POST, OPTIONS'); 
header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Request-With'); 
header('Access-Control-Allow-Credentials', 'true'); 

При угловом js.Если вы используете < 1.2, вы можете установить CORS в файле контроллера следующим образом. В последней версии не требуется установка default.you нужно установить, какой тип содержимого, который вы ожидаете от сервера по умолчанию, json.If ваш ожидающий другой тип контента, который вы можете установить вручную в запросе.

myApp.config(['$httpProvider', function($httpProvider) { 
      $httpProvider.defaults.useXDomain = true; 
      delete $httpProvider.defaults.headers.common['X-Requested-With']; 
     } 
    ]); 
0

Когда вы вызываете запрос XHR с крестом, javascript сначала запускает запрос OPTIONS к данному URL-адресу. Если этот метод не добавлен в ваши маршруты, он выдает страницу 404, которая подается без заголовка ACAO, поэтому конкретный запрос POST не будет отправлен, так как javascript видит, что это не разрешено.

0

добавить

<?php header("Access-Control-Allow-Origin: *"); ?> 

общественному/index.php, если он не работает в функции, как голубые колокольчики предложил

0

Добавьте эти строки в общественном/index.php:

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'); // allow certain headers 

См., Если это работает.