Http请求多浏览器问题

时间:2016-03-02 13:41:31

标签: angularjs http laravel cross-browser

我使用laravel 5.1angularJs中构建。

当用户点击某个按钮时,我想发送一个destroy request从数据库中删除它,然后当它完成时发送get request以获取新数据,现在已经删除了一个。

所以我将我的方法附加到一个按钮上的ng-click事件,这是有效的,它命中了该方法。

然后我运行.destroy request。在.then()的{​​{1}}方法内,我想调用另一个具有.destroy的方法。

这在Safari中完美运行,但在Chrome或Firefox中无效。

.get request,按钮点击删除时调用的方法为Here is my code for the controller

deleteOpportunity()

我的服务代码:

$scope.getOpportunities = function()
    {
        UBOService.get()
            .then(function successCallback(responsed) {
                $scope.opportunities = responsed.data;
            }, function errorCallback(response) {
                $scope.error = response;
            });
    }
$scope.deleteOpportunity = function()
    {

                UBOService.destroy($scope.activeItem.id)
                    .then(function successCallback(response) {
                        $scope.getOpportunities();

                        return false;
                    }, function errorCallback(response) {
                        $scope.error = response;
                    });

    }

我做错了吗?有什么我想念的吗? Safari如何与此代码进行不同的交互,使其有效?

3 个答案:

答案 0 :(得分:3)

很难根据您发布的参数来衡量,但只是基于您说这在Safari中完美运行,但在Chrome或Firefox中不起作用,听起来这可能是一个CORS问题。

Firefox和Chrome对跨源请求的要求与Safari不同。此destroy操作的Laravel api端点是否位于与Angular应用相同的位置?返回API的Access-Control-Allow-Origin标头是什么?

尝试向Laravel添加类似以下内容的内容,看看它是否使这个块在这些浏览器中保持一致:

App::before(function($request) {
  // Enable CORS 
  // In production, replace * with http://yourdomain.com 
  header("Access-Control-Allow-Origin: *");
  header('Access-Control-Allow-Credentials: true');

  if (Request::getMethod() == "OPTIONS") {
    // The client-side application can set only headers allowed in Access-Control-Allow-Headers
    $headers = [
      'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE',
      'Access-Control-Allow-Headers' => 'X-Requested-With, Content-Type, X-Auth-Token, Origin, Authorization'
    ];
    return Response::make('You are connected to the API', 200, $headers);
  }
});

(^ source)

答案 1 :(得分:2)

我猜它是一个CORS问题。此外,如果您将客户端与服务器端分离,通常会发生此问题。您需要创建一个中间件来处理此类问题。

TopLevel

在角度方面添加此配置块

namespace App\Http\Middleware;

use Closure;

class BeforeMiddleware
{
  /**
  * Handle an incoming request.
  *
  * @param  \Illuminate\Http\Request  $request
  * @param  \Closure  $next
  * @return mixed
  */
 public function handle($request, Closure $next)
 {
    /** 
    * The access control allow origin and 
    * allow credential is set to * and true 
    * because i allow request from different domains
    * to hit the server
    */
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Credentials: false');
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization');

    if ($request->getMethod() == "OPTIONS") {
        $headers = array(
            'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers'=> 'X-Requested-With, content-type',);
        return Response::make('', 200, $headers);
    }

    return $next($request);
 }
}

答案 2 :(得分:0)

如果您在successCallbackerrorCallback中返回值,则返回的值将用于解析promise。 尝试定义一个$q.deferred,它将在使用数据获取$ http成功时解决。

$scope.deleteOpportunity = function() {
            var deferred = $q.defer();

            UBOService.destroy($scope.activeItem.id)
                .then(function successCallback(response) {
                    UBOService.get().then(function(response){
                        $scope.opportunities = response.data;
                        deferred.resolve(response.data);
                    };
                }, function errorCallback(response) {
                    $scope.error = response;
                });
        return deferred.promise;
}