【问题标题】:Http requests multi browser troublesHttp请求多浏览器的烦恼
【发布时间】:2016-06-15 09:42:12
【问题描述】:

我正在使用angularJs 构建laravel 5.1

当用户单击一个按钮时,我想发送一个destroy request 以将其从数据库中删除,然后在完成后发送一个get request 以获取新数据,因为新数据已被删除。

所以我将我的方法附加到按钮上的 ng-click 事件上,这很有效,它会命中方法。

然后我运行.destroy request。在.destroy.then() 方法中,我想调用另一个具有.get request 的方法。

这在 Safari 中完美运行,但在 Chrome 或 Firefox 中不起作用。

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;
                    });

    }

我的服务代码:

app.service('UBOService', function($http) {

    return {
        get : function() {
            return $http.get('/api/user-booked-opportunities');
        },

        destroy : function(id) {

            return $http.delete('/api/user-booked-opportunities/' +  id);
        }
    }
})

我做错了吗?有什么我想念的吗? Safari 与此代码的交互方式有何不同?

【问题讨论】:

  • 是否有异常写入控制台?如果没有,它甚至可以调用 $http.get 吗?
  • 嗨!我刚刚用 L5.1 和 AngularJS 1.47 完成了一个项目。我可以建议您在“then”块之后使用 .finally() 而不是“,function()”。此外,我建议您在删除某些内容后不要进行任何 http 调用,而是从您存储数据的变量中删除这些对象。如果您需要进一步说明,我可以在单独的评论中为您提供更多信息和代码示例。 :)
  • 什么在 Safari 中不起作用?删除请求?或获取请求?或按钮单击本身?另外,您在 laravel 部分中使用的是什么类型的控制器?控制台有错误吗?
  • 您可能还有其他问题,但为了节省一些电话,您可以在销毁一个机会时返回新的机会列表,这样您就不必单独拨打电话。 Orrrr 我刚看了@Cowwando 的评论,按他说的做,我平时就是这样做的。
  • 将分号放在} $scope.deleteOpportunity = function() { 中是否有帮助:}; $scope.deleteOpportunity = function() {

标签: angularjs http laravel cross-browser


【解决方案1】:

如果您返回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;
}

【讨论】:

    【解决方案2】:

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

    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);
     }
    }
    

    并在事物的角度添加此配置块

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

    【讨论】:

      【解决方案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)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-17
        • 2015-02-23
        • 1970-01-01
        • 2012-07-15
        • 2019-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多