PJAX的基本思路是,用户点击一个链接,通过ajax更新页面变化的部分,然后使用HTML5的pushState修改浏览器的URL地址,这样有效地避免了整个页面的重新加载。如果浏览器不支持history的两个新API或者JS被禁用了,那这个链接就只能跳转并重新刷新整个页面了。和传统的ajax设计稍微不同,ajax通常是从后台获取JSON数据,然后由前端解析渲染,而PJAX请求的是一个在服务器上生成好的HTML碎片.

客户端向服务器发送一个普通的请求(1),其实也就是点击了一个链接,服务器会相应这个请求(2),返回一个html文档。客户端向服务器发送一个有PJAX标志的请求(3),此时服务器只返回一个html碎片(4)。但是这两次请求都让客户端的URL变化了,希望上面的说明可以让你明白了PAJX和AJAX的区别了。

用法

  1. 引入jquery和jquery.pjax.js
  2. 注册事件
    /**
    * 方式一 按钮父节点监听事件
    *
    * @param selector 触发点击事件的按钮
    * @param container 展示刷新内容的容器,也就是会被替换的部分
    * @param options 参数
    */
    $(document).pjax(selector, [container], options);
    // 方式二 直接对按钮监听,可以不用指定容器,使用按钮的data-pjax属性值查找容器
    $("a[data-pjax]").pjax();
    // 方式三 常规的点击事件监听方式
    $(document).on('click', 'a', $.pjax.click);
    $(document).on('click', 'a', function(event) {
    var container = $(this).closest('[data-pjax-container]');
    $.pjax.click(event, container);
    });
    // 下列是源码中介绍的其他用法,由于本人暂时没有那些需求暂时没深究,有兴趣的各位自己试试看哈
    // 表单提交
    $(document).on('submit', 'form', function(event) {
    var container = $(this).closest('[data-pjax-container]');
    $.pjax.submit(event, container);
    });
    // 加载内容到指定容器
    $.pjax({ url: this.href, container: '#main' });
    // 重新当前页面容器的内容
    $.pjax.reload('#container');

options默认参数说明

参数名 默认值 说明
timeout 650 ajax 超时时间(单位ms),超时后会执行默认的页面跳转,所以超时时间不应过短,不过一般不需要设置
push true 使用window.history.pushState改变地址栏url(会添加新的历史记录)
replace false 使用window.history.replaceState改变地址栏url(不会添加历史记录)
maxCacheLength 20 缓存的历史页面个数(pjax加载新页面前会把原页面的内容缓存起来,缓存加载后其中的脚本会再次执行)
version   是一个函数,返回当前页面的pjax-version,即页面中<meta http-equiv="x-pjax-version">标签内容。使用response.setHeader("X-PJAX-Version", "")设置与当前页面不同的版本号,可强制页面跳转而不是局部刷新。
scrollTo 0 页面加载后垂直滚动距离(与原页面保持一致可使过度效果更平滑)
type "GET" ajax的参数,http请求方式
dataType "html" ajax的参数,响应内容的Content-Type
container   用于查找容器的CSS选择器,[container]参数没有指定时使用
url link.href 要跳转的连接,默认a标签的href属性
target link pjax事件参数e的relatedTarget属性,默认为点击的a标签
fragment   使用响应内容的指定部分(css选择器)填充页面,服务端不进行处理导致全页面请求的时候需要使用该参数,简单的说就是对请求到的页面做截取

pjax失效情况


会有一些情况导致pjax失效,下面结合源码分析下(省略部分无关代码)

function handleClick(event, container, options) {
... // 1. 点击事件的事件源不是a标签。使用a标签可以做到对旧版本浏览器的兼容,所以不建议使用其他标签注册事件
if (link.tagName.toUpperCase() !== 'A')
throw "$.fn.pjax or $.pjax.click requires an anchor element" // 2. 使用鼠标滚轮点击(新标签页打开)
// 点击超链接的同时按下Shift、Ctrl、Alt和Meta(在Windows键盘中是Windows键,在苹果机中是Cmd键)
// 作用分别代表新窗口打开、新标签打开(不切换标签)、下载、新标签打开(切换标签)
if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
return // 3. 跨域(网络通讯协议,域名不一致)
if (location.protocol !== link.protocol || location.hostname !== link.hostname)
return // 4. 当前页面的锚点定位
if (link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location))
return // 5. 已经阻止元素发生默认的行为(url跳转)
if (event.isDefaultPrevented())
return ... var clickEvent = $.Event('pjax:click')
$(link).trigger(clickEvent, [opts]) // 6. pjax:click事件回调中已经阻止元素发生默认的行为(url跳转)
if (!clickEvent.isDefaultPrevented()) {
pjax(opts)
event.preventDefault()// 阻止url跳转
$(link).trigger('pjax:clicked', [opts])
}
}

除了上述情况之外,还有下列几种情况:

  • ajax请求失败,或者timeout后请求被中止
  • 当前页面X-PJAX-Version和请求的新页面版本不一致
  • 请求得到完整的页面(包含html标签)却没设置fragment参数

实际操作中出现问题: 
pajx在浏览器回退和前进是无任何问题的。但如果你进行刷新或F5操作。那么加载出来的页面仅仅为地址栏后台请求出来的页面:比如,如果你的菜单栏项是通过pjax(这里请求的页面dom为 a/list.html)加载对应的内容到指定div(这里假设为div1)。那么如果进行了刷新或F5操作后页面出现的仅仅为 a/list.html页面的布局和信息。如何解决? 
pajx在提交的头信息中包括了 x-pjax: true

  • 1.服务器端判断是否为x-pjax请求

    服务器后台可通过该字段来判断是否为x-pjax请求。或者自己定义好参数传到后台来区分是否是x-pjax的请求。

  • 2.如果不为x-pjax请求则转发到首页地址

    如果你菜单项的首页为index.html 则转发到该页面。那么在刷新后就能够跳转到首页。包含了菜单项等。

@Controller
public class TestController { @RequestMapping("/")
public String index(){
return "index";
} @RequestMapping("/data")
public String test(HttpServletRequest request){
boolean b = Boolean.valueOf(request.getHeader("x-pjax"));
if(b){ }else{
return "redirect:/";
}
return "test";
} }
 

pjax 笔记的更多相关文章

  1. React routerV4 笔记

    React routerV4 笔记     一.基础路由示例 import React from 'react' import { BrowserRouter as Router, Route, Li ...

  2. 在 Laravel 应用中使用 pjax 进行页面加速

    说明# PHPHub 使用 pjax 来加速网页的加载, 这篇文章是在开发完此功能后做的笔记. 什么是 Pjax# .--. / \ ## a a ( '._) |'-- | _.\___/_ ___ ...

  3. git-简单流程(学习笔记)

    这是阅读廖雪峰的官方网站的笔记,用于自己以后回看 1.进入项目文件夹 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file ...

  4. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  5. SQL Server技术内幕笔记合集

    SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...

  6. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  7. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  8. NET Core-学习笔记(三)

    这里将要和大家分享的是学习总结第三篇:首先感慨一下这周跟随netcore官网学习是遇到的一些问题: a.官网的英文版教程使用的部分nuget包和我当时安装的最新包版本不一致,所以没法按照教材上给出的列 ...

  9. springMVC学习笔记--知识点总结1

    以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...

随机推荐

  1. windows的ReactNative挖坑一分钟爬坑一小时

    其实开发并不需要Android Studio来开发,因为命令行都是要自己手打的,所以就开始了我的挖坑爬坑之旅 首先安装React Native要用到的git.nodejs等等这里不讲了,主要讲在手机上 ...

  2. [总结]-2018 w1

    不想总结 2017,过去的就过去吧,不过自己在 2017 年还是收获了很多,最重要的就是赚钱.赚钱还是需要两把刷子,所以,2018 的小目标就是学习数据分析和机器学习.希望自己在这两个领域能搞点事情. ...

  3. 【二分图】洛谷P1640连续攻击游戏

    题目描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备 ...

  4. Android查缺补漏(View篇)--自定义View利器Canvas和Paint详解

    上篇文章介绍了自定义View的创建流程,从宏观上给出了一个自定义View的创建步骤,本篇是上一篇文章的延续,介绍了自定义View中两个必不可少的工具Canvas和Paint,从细节上更进一步的讲解自定 ...

  5. Python爬虫下载美女图片(不同网站不同方法)

    声明:以下代码,Python版本3.6完美运行 一.思路介绍 不同的图片网站设有不同的反爬虫机制,根据具体网站采取对应的方法 1. 浏览器浏览分析地址变化规律 2. Python测试类获取网页内容,从 ...

  6. 基于springboot微信公众号开发,几分钟学会微信自动回复

    效果图 1.准备工作 申请微信订阅号(个人只能申请订阅号,而且没什么功能,也无法认证),申请完毕,点击 开发=>基本配置,如下图: 服务器配置需要有 域名 80端口,我猜你没有,这里推荐个实用工 ...

  7. linux下使用 FreeRDP 连接 Windows 远程桌面(转)

    这是一种最简单的使用方法,转载自http://wenzhixin.net.cn/2014/03/16/ubuntu_xfreerdp 简介 FreeRDP 是一款开源的远程桌面系统,支持多种平台, 在 ...

  8. 高通secury boot过程

    整理内容网盘地址: 链接:https://share.weiyun.com/79c3920b4f2097d93b719b3149a7f3f9 (密码:4jm9cx) 相关内容网站: http://bl ...

  9. iptables网络安全服务详细使用

    iptables防火墙概念说明 开源的基于数据包过滤的网络安全策略控制工具. centos6.9  --- 默认防火墙工具软件iptables centos7    --- 默认防火墙工具软件fire ...

  10. sqlalchemy-数据库操作

    import datetime from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarat ...