【问题标题】:Laravel: strange behavior when I try to serve ajax and non-ajax request on same route (Caching)Laravel:当我尝试在同一条路由上提供 ajax 和非 ajax 请求时出现奇怪的行为(缓存)
【发布时间】:2013-07-03 12:26:11
【问题描述】:

我为laravel.dev/test 注册了GET 路由。路由对应的控制器会区分请求是否为ajax。

当我在浏览器上输入 laravel.dev/test 时,Laravel 检测到它不是 ajax 请求并使用 return View::make() 生成页面。然后页面上的Backbone.js 代码向laravel.dev/test 发出ajax 请求,Laravel 使用return Response::json 返回一个JSON。

这一切都很好,直到我尝试离开页面然后使用浏览器按钮导航回 laravel.dev/test 它打印出 json 作为响应,这不是我所期望的,因为我不是发出 ajax 请求。

【问题讨论】:

  • 我猜你没有先发出 ajax 请求,然后是“正常”请求,然后单击后退按钮?您如何检测普通请求和 ajax 请求之间的差异?并进行调试,在意外的 ajax 响应中打印发送的标头:)
  • Request::ajax() 可用于测试 ajax 请求。意外的标头:Request URL:http://laravel.dev/test Request Method:GET Status Code:200 OK (from cache)
  • 听起来像是缓存问题。使用浏览器的开发工具来查看是否确实发出了请求并将 json 作为响应,或者是否从缓存中获取。编辑:现在我们知道这是一个缓存问题。
  • @Alex-Info.net 我拍了一张 chrome 开发工具的照片:i.imgur.com/N7uBb3v.png

标签: laravel laravel-4


【解决方案1】:

绝对是缓存问题。只是为了尝试获得一些结果,将其添加到您的控制器(ajax 和非 ajax)以强制禁用缓存:

header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past

并查看 chrome 是否仍从后退按钮上的缓存中获取。

【讨论】:

  • 我尝试在返回 View::make 之前放置您的代码,我还尝试了 $response = Response::make(View::make()); 然后 $respose->header('Cache-Control', 'no-cache, must-revalidate') 用于 ajax 和非 ajax,但它仍然不起作用。
  • 浏览器在后退按钮上从缓存加载页面是正常行为,您正在打一场可能是一场失败的战斗。最后一次尝试:header("Cache-Control: no-cache, max-age=0, must-revalidate, no-store");(来自blog.55minutes.com/2011/10/…)。否则你真的应该为 ajax 和非 ajax 使用不同的路由。
  • 它有点工作在那个后退按钮不再返回 JSON。但是 Backbone.js 的功能完全被破坏了。为了避免调试我的 Backbone 代码,我想我会永远使用不同的路由方法。
  • 只是因为我真的很好奇,主干是如何/为什么被这个标题“完全破坏”的?你得到什么reault?另外,很高兴你走的是不同的路线,干净多了。
  • 我的backbone.js代码在初始化时会fetch()来自服务器的一个json来填充一个集合,然后传递给一个集合视图,然后在页面上呈现一些html标签。以前在我添加缓存控制之前,它是“半损坏”的,因为我必须刷新几次才能在页面上呈现某些内容(有时它只是显示一个空白页面)。
【解决方案2】:

这不是 laravel 或骨干网,而是 chrome issue! Check this out too.

对我有用的解决方案是把

return Response::json($this->data)->header("Vary", "Accept");

祝你好运!

【讨论】:

    【解决方案3】:

    这是在 Laravel 5.1 中,但该原则也适用于所有以前的版本。

    我处理它的方式是两条路由指向同一个方法,但一条以.json 扩展名结尾:

    get('items', ['as' => 'items', 'uses' => 'ItemsController@index']);
    get('items.json', ['as' => 'items', 'uses' => 'ItemsController@index']);
    

    然后在我的index()方法里面:

    $data = []; // your collection
    
    if ($this->request->ajax()) {
        return response()->json($data); // replace with actual JSON data
    }
    
    return view('items.index', compact('data')); 
    

    这允许 JSON 响应的专用 URL,使用相同的方法和数据,并且永远不会干扰我的后退按钮。

    【讨论】:

      猜你喜欢
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-30
      • 1970-01-01
      • 2017-09-13
      • 2011-09-03
      • 1970-01-01
      相关资源
      最近更新 更多