Http请求多浏览器的烦恼
Posted
技术标签:
【中文标题】Http请求多浏览器的烦恼【英文标题】:Http requests multi browser troubles 【发布时间】: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()
【参考方案1】:
如果您返回successCallback
或errorCallback
中的值,则返回的值将用于解析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)
【讨论】:
以上是关于Http请求多浏览器的烦恼的主要内容,如果未能解决你的问题,请参考以下文章