0

0

Ajax浅析与实操

一个新手

一个新手

发布时间:2017-09-09 10:39:47

|

1411人浏览过

|

来源于php中文网

原创

开头那些话

目的

首先鄙人是一名信管人,本科学习的是ssh框架后台java开发(学得一塌糊涂)。平时开发web项目都是用jsp做页面直出,然后各种form表单提交,action跳转;导致一旦需要更新数据就要刷新页面,哪怕是一小部分地方;很是麻烦,也影响用户体验。我就一直想用一种技术来解决这个问题。所以私底下折腾了一阵子,看了看ajax,发现struts2完美支持ajax,所以写下这篇文章,以供和我有过一样故事的人参考!(ps:平时私底下班上有同学问过我,所以干脆整理出来,做做参考!)

事先准备

这篇文章主要是讲struts2环境下的ajax应用。所以你事先需要在你的Web项目里面导入struts2所有相关jar包,这个学过的人都知道,这里就不多赘述;除此之外还需导入一个额外的jar包,用来支持json数据格式;jar包我会以附件形式发出来。基本上做完这些就可以开始了!


具体实现

具体我会讲两个例子,一个用来讲述ajax请求的具体流程,另一个就与实际应用有关了——根据参数返回对应的数据。

页面代码(HTML+CSS+JS)

先贴代码1(为了方便,我就没有贴jsp代码,其实也就标签一些配置项而已,读者可以自己复制)

<!DOCTYPE html><html lang="zh-CN"><head>
  <meta charset="UTF-8">
  <title>XHR</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <style>
    form, .box {      
    margin: 50px;      
    padding: 20px;    
    }

    form p {      
    margin: 20px 0;    
    }

    .box {      
    background-color: rgba(0, 0, 0, 0.2);      
    height: 40px;      
    width: 300px;    
    }
  </style></head><body>
  <form id="form">
    <p><label for="nick">昵称:</label> <input value="jero" name="nick" id="nick" type="text" required></p>
    <p><label for="love">爱好:</label> <input value="coding" name="love" id="love" type="text" required></p>
    <p>
      <button type="button" name="get">Get 提交</button>
      <button type="button" name="post">Post 提交</button>
    </p>
  </form>
  <p id="box" class="box"></p>
  <script>

    var byId = (id) => document.getElementById(id); // ES6 箭头函数
    var form = byId('form');    var box = byId('box');    /**
     * 表单的数据收集起来
     */
    function getData(type) {
      var result = [];      
      var isFill = false;      // 都是文本框的 name
      ['nick', 'love'].forEach((fieldName) => {        
      var v = form[fieldName].value;        
      var obj = {};        
      if (v) {
         obj[fieldName] = v;
          result.push(obj);
          isFill = true;
        } else {
          isFill = false;
        }
      });      if (!isFill) { // 没填的话要返回没填的结果 false
        return false;
      }
      result = JSON.stringify(result);
      result = "info" + '=' + encodeURIComponent(result) 
      return result;
    }    function request(type, callback) {
      var data = getData(type);      
      if (!data) { // 没填的话直接警告
        return alert("完成表单!");
      }      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = () => {        
      if (xhr.readyState === 4) {
          callback(JSON.parse(xhr.responseText), xhr);
        } else {
          console.log(xhr.status);
        }
      }

      xhr.open(type, './xhr' + (type === 'get' ? `?${data}` : '')); // get 的参数直接拼在 url 的末尾

      // 模拟 post 请求,必须设置个请求头
      if (type === 'post') {
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')//可以自己根据实际情况改变取值
      }

      xhr.send(type === 'get' ? null : data);
    }    /**
     * 绑定事件抽象下
     */
    function click(btn, callback) {
      btn.addEventListener('click', () => {
        request(btn.name, (data) => {         
        var data = JSON.parse(data);
          box.innerHTML = `success by ${data[0].type} method!<br>
         ${data[0].infoStr}`;
         console.log(data);
        });
      });
    }

    // 绑定事件,代码可以从这里看
    click(form.get);
    click(form.post)  </script></body></html>

页面运行效果
这里写图片描述
上面代码中有几处在这说一下。1.encodeURIComponent()这个函数是用来把变量转换成url地址中的字符串,避免传值时出现乱码。2.当使用var form = document.getElementById('form')获取到form表单节点时,我们可以直接使用form.nick或者form[nick]来直接获取昵称输入框节点,当然前提是form表单中的元素且设置了name属性。
然后我们来重点解读下这段代码:

function request(type, callback) {      var data = getData(type);//参数列表字符串

      if (!data) { // 没填的话直接警告
        return alert('完成表单!');
      }      var xhr = new XMLHttpRequest();//生成XHR对象

      xhr.onreadystatechange = () => {        if (xhr.readyState === 4) {
          callback(JSON.parse(xhr.responseText), xhr);//数据成功接收后的回调函数
        } else {
          console.log(xhr.status);
        }
      }

      xhr.open(type, './xhr' + (type === 'get' ? `?${data}` : '')); // get 的参数直接拼在 url 的末尾

      // 模拟 post 请求,必须设置个请求头
      if (type === 'post') {
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')//可以自己根据实际情况改变取值
      }

      xhr.send(type === 'get' ? null : data);
    }

首先,明确一点这个函数的作用就是发送ajax请求;这里我采用了原生的XHR对象来实现ajax请求,目的是让大家能够深刻理解到ajax 是怎么样一回事;总体来说发送ajax请求分为四步:

一、创建XHR对象

IE7以上以及现在主流的浏览器都支持原生的XHR对象,所以我们可以直接用var xhr = new XMLHttpRequest();来创建XHR对象,用XHR对象所封装的一些方法来实现ajax请求。至于IE7以下的毒瘤,我是绝对不会做考虑的!如果你硬要做IE7以下的兼容可以参考js红皮书ajax章节。是通过ActiveX对象来创建的!

HiShop网店代理分销系统
HiShop网店代理分销系统

Hishop.5.2.BETA2版主要更新: [修改] 进一步优化了首页打开速度 [修改] 美化了默认模板 [修改] 优化系统架构,程序标签及SQL查询效率,访问系统页面的速度大大提高 [修改] 采用了HTML模板机制,实现了前台模板可视化编辑,降低模板制作与修改的难度. [修改] 全新更换前后台AJAX技术框架,提升了用户操作体验. 店铺管理 [新增] 整合TQ在线客服 [修改] 后台广告位增加

下载

二、绑定监听函数

xhr.onreadystatechange实现监听请求响应过程所处的的阶段。主要是通过XHR对象的readyState属性;属性的取值为:
0-未初始化(未调用open()方法)
1-启动(调用open()方法,未调用send()方法)
2-发送(调用send()方法,但没有得到响应、没有接收到数据)
3-接收(接收到部分数据)
4-完成(得到全部响应数据)
当属性值每发生一次变化,就触发一次readystatechange事件。所以我们可以通过这个属性的值来判断我们所需的数据是否准备就绪。以便及时地将我们所请求的数据渲染到页面中去。
xhr.status返回的则是HTTP请求的状态码( 学过网络的同学应该都了解),这就方便我们检测请求是否成功,亦或者判断请求失败的原因。
callback(JSON.parse(xhr.responseText), xhr);这个则是我们接收到全部数据时所要执行的回调函数,主要用来处理接收的数据,进行页面渲染。大家在实际应用时可以照写,重点是绑定函数中该回调函数的编写,大家则要根据实际需要进行编写。

三、启动请求

xhr.open(type, './xhr' + (type === 'get' ??${data}: ''));

第一个参数主要设置请求是使用get方法还是post方法,(ps:最近有文章说了这两者根本没什么区别,在这里我们暂且遵循老套路),第二个则是请求的目标地址,运用了一个三目运算来区分get和post因为get方法的传参是通过将参数放到url一并发送到后台的,所以我们要进行字符串的拼接;而post是通过请求头中的Form Data传递的;如下图:
这里写图片描述

四、发送请求

xhr.send(type === 'get' ? null : data);最后一个环节,上面说到的post传参就要在这传入,get则不用,所以在这里同样用了一个三目运算。

基本上,原生的XHR对象实现ajax请求就如上所说;是不是觉得有点复杂?那么不用慌,喜欢“偷懒”的高端程序猿已经帮我们实现了封装;没错就是当初影响世界的jQuery。话不多说,直接上代码:

$.ajax(function() {
    url: 'xhr',
    type: 'get',
    dataType: 'json',//返回数据类型
    data: {info: data},//传参
    success: function(data) {
        /***/
    },
    error: function() {
        console.log('error!');
    }
});

jQuery提供了很多种写法,包括更简单的$.getJSON();至于我为什么要推荐这种写法,大家可以理解成我很笨,但是其中的含义大家用过就明白了!(吹个小牛皮)

后台代码(action+struts.xml)

上面说了这么多,一是让大家了解原生的是怎样的一个东西,二是因为上述部分是学习后台同学没有接触过的,所以尽可能的讲清楚点;这部分,我想代码一贴出来,大家都懂了!
action

package com.testforajax.demo.action;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import org.apache.struts2.ServletActionContext;import net.sf.json.JSONArray;import net.sf.json.JSONObject;import com.opensymphony.xwork2.ActionSupport;public class AjaxDemo extends ActionSupport {
    private String info;    public String getInfo() {        return info;
    }    public void setInfo(String info) {        this.info = info;
    }    public String execute() throws Exception {
        String method = ServletActionContext.getRequest().getMethod();
        HashMap<String, String> map = new HashMap<String, String>();
        String name;
        String love;
        JSONArray json = JSONArray.fromObject(info);
        name = json.getJSONObject(0).getString("nick");
        love = json.getJSONObject(1).getString("love");
        json.clear();
        String result = name + " very love " + love;
        map.put("type", method);
        map.put("infoStr", result);
        json.add(map);
        info = json.toString();
        System.out.println(this.info);        return "success";
    }
}

struts.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"><struts>
    <!-- XHR演示 -->
    <package name="xhrTest" extends="json-default, struts-default">
        <action name="xhr" class="com.testforajax.demo.action.AjaxDemo">
            <result type="json">
                <param name="root">info</param>
            </result>
        </action>
        <!--
        <action name="newxhr" class="com.testforajax.demo.action.AjaxDemo2">
            <result type="json">
                <param name="root">queryId</param>
            </result>
        </action>
        -->
    </package></struts>

在这里只强调一点,struts2的自动打包传值,一定要保证参数名一致!即你在前台封装json数据格式时,对应的key值要和struts.xml配置文件中<param name="root">info一致,同时在action类中也要有对应的属性,以及getter和setter。
还有,在使用json数据格式时要做到传参时记得JSON.stringify(),渲染响应数据时记得JSON.parse()。封装时,一定要按照标准格式,后台封装的话,推荐我写的那种先用map做处理。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

463

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

135

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

64

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

26

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

14

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

524

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

53

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号