八、Ajax基础
1. RIC和传统Web
1.1 RIC
- RIC(Rich Internet Application):富客户端英特网应用程序。将内容都放在客户端
- 特点
- 更加丰富绚丽的界面元素
- 局部刷新(无刷新) :节省网络带宽资源
- 异步调用:免去等待webServer响应,更连续体验
- 三种实现
1.2 传统web

- 缺点
- 重新加载页面所有内容,加重server负担,浪费带宽
- 只能保存请求发出前的用户操作
- 响应结束前用户处于等待状态,交互不连贯
- 界面需要大量css,js代码
2. Ajax
2.1 Ajax简介
- Ajax:Asynchronous JavaScript And XML(异步的JS和XML)
- 局部刷新(无刷新)
- 刷新页面局部区域,节省网络带宽资源,减轻webServer负担
- 异步调用
- 用户在请求的同时依旧可以做别的事,Ajax引擎在后台自动请求服务器,用户免去等待webServer响应
- 实际意义
- 不发生页面跳转、不刷新页面、异步载入内容并改写页面内容的技术
- 理解为通过JS向服务器发送请求
- Ajax:一种不用刷新整个页面便可与服务器通讯的办法
- Ajax缺点
- 页面局部刷新,导致后退等功能失效
- 模型对比
- 传统模型
- 客户端向服务器发送一个请求,服务器返回整个页面,如此反复
- 客户端向服务器发送一个请求,服务器返回整个页面,如此反复
- Ajax模型
- 数据在客户端与服务器之间独立传输。服务器不再返回整个页面
- 数据在客户端与服务器之间独立传输。服务器不再返回整个页面
- 传统模型
2.2 Ajax描述
- AJAX 并非编程语言
- Ajax的组合
- 浏览器内建的 XMLHttpRequest 对象(从 web 服务器请求数据)
- JavaScript 和 HTML DOM(显示或使用数据)
- 使用XMLHTTP组件XMLHttpRequest对象进行异步数据读取
- 使用JavaScript绑定和处理所有数据
- Ajax原理
- 原理1
- 原理2
- 原理1
2.3 Ajax工作流程

2.4 同步与异步
- 同步处理
- 用户向服务器发送一个请求时,在服务器响应之前,该用户不能进行任何操作,只能等待服务器响应
- 即使整个页面中只有一小部分内容发生改变,也要刷新整个页面
- 异步处理
- 用户发送请求时,通过AJAX向服务器发送请求,发送请求时,该用户可以进行任何操作。当服务器响应结束后,响应信息会直接发送到AJAX中,AJAX根据响应内容做处理
- AJAX可以根据服务器的响应信息局部的修改页面,而不需要整个页面刷新
2.5 Ajax的使用步骤
-
创建XMLHttpRequest对象
- 如:xhttp = new XMLHttpRequest();
- 如:xhttp = new XMLHttpRequest();
-
定义回调函数
- xhttp.onreadystatechange = returnFunction
- xhttp.onreadystatechange = returnFunction
-
规定请求的类型,初始化XMLHttpRequest组件
- 如:xhttp.open("GET", "AjaxServletText?uname="+uname, true);
- 如:xhttp.open("GET", "AjaxServletText?uname="+uname, true);
-
向服务器发送请求
- 如:xhttp.send();
- 如:xhttp.send();
-
书写回调函数
javafunction dianji() { var uname = document.getElementById("uname").value; // 1. 创建XMLHttpRequest对象 var xhttp = new XMLHttpRequest(); // 2. 定义回调函数 xhttp.onreadystatechange = returnFunction; // 3. 初始化组件,规定请求类型 xhttp.open("GET", "AjaxServletText?uname=" + uname, true); // 4. 发送请求 xhttp.send(); } function returnFunction() { if (this.readyState == 4 && this.status == 200) { var returnData = this.responseText; console.log(returnData); } }
- 两种方式比较
3. XMLHttpRequest对象
3.1 XMLHttpRequest概述
- XMLHttpRequest(通常简称为 XHR)是一个浏览器内置的JavaScript对象,它允许从服务器异步加载数据
- XMLHttpRequest 对象用于在后台与 Web 服务器交换数据
- 可以更新网页的部分内容,而无需重新加载整个页面
- XMLHttpRequest的创建
- new XMLHttpRequest();
- 如:xhttp = new XMLHttpRequest();
3.2 属性
- 属性名
-
Onreadystatechange
- 设置回调函数(状态改变一次调用一次,会调用四次)
javaxhttp.onreadystatechange = returnFunction
- 该事件处理函数由服务器触发,在 Ajax 执行过程中,服务器会通知客户端当前的通信状态
-
readyState
- 表示Ajax请求的当前状态
javascriptxhttp.readyState == 4
- 0: 请求未初始化。还没有调用 open 方法
- 1: 服务器连接已建立。 open 方法已被调用,但 send 方法还没有被调用
- 2: 请求已接收。send 已被调用。请求已经开始
- 3: 正在处理请求。服务器正在发送响应
- 4: 请求已完成且响应已就绪。响应发送完毕
- 每次 readyState 值的改变,都会触发 readystatechange 事件
-
status
- 服务器应答状态码
javaxhttp.status == 200
- 200: "OK"
- 403: "Forbidden"
- 404: "Page not found"
-
responseText
- 获取字符串形式的响应数据
javavar returnDate = xhttp.responseText;
-
responseXML
- 获取 XML 数据形式的响应数据
javavar returnXml = xhttp.responseXML;
- MIME 类型必须为 text/xml
javaresponse.setContentType("text/xml;charset=utf-8");
-
3.3 方法
-
open(method,url,asynch):规定请求的类型,初始化XMLHttpRequest组件
- method:请求类型,如:get、post等
- url:路径字符串,指向所请求的服务器上的文件,如:SaveUserServlet
- asynch:请求传输方式
- true:异步请求
- false:同步请求
javaxhttp.open("GET", "AjaxServletText?uname="+uname, true);
-
send():向服务器发送请求
- get请求时无参数
- post请求时参数访问服务器时携带的数据
javaxhttp.send();
-
使用post请求时需要设置请求消息头
- 在open()和send()之间添加xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- 在open()和send()之间添加xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
4. JSON详解
4.1 JSON简介
- JSON(JavaScript Object Notation):JavaScript 对象标记法,一种简单的数据传输格式
- 什么是JSON?
- JSON 是一种存储和交换数据的语法
- JSON 是通过 JavaScript 对象标记法书写的文本
- JSON独立于语言
- JSON是JavaScript原生格式,在JavaScript中处理JSON数据不需要任何特殊的API或工具包
4.2 JSON规则
- 对象是一个无序的"名称/值对"集合
- 一个对象以" { "开始," } "结束
- 每个"名称"后跟一个" : "
- "名称/值对"之间使用" , "分隔
- 键必须是字符串,由双引号包围
- 花括号容纳对象,方括号容纳数组
- 对象描述中存储的数据可以是字符串,数字或者布尔值。也可存储函数(对象的方法)
4.3 解析JSON
- JSON 只是一种文本字符串。它被存储在 responseText 属性中
- JSON 是同 web 服务器进行数据传输
- 数据在浏览器和服务器交互的过程中,数据永远是字符串
- 通过 JSON.parse() 解析数据,可以将以 JSON 格式写的文本数据(字符串)转化成 JSON对象
- 通过 JSON.stringify() 解析数据,可以将JSON对象转化成以 JSON 格式写的文本数据(字符串)
4.4 JSON与字符串转换方法
-
JSON.parse()
- 将字符串转换成Json对象
- 字符串必须以 JSON 格式书写,否则会出现语法错误
javavar myObj = JSON.parse(str);

-
JSON.stringify()
- 将Json对象转换成字符串
- 在 JSON 中,不允许日期对象。JSON.stringify() 函数将把任何日期转换为字符串
javavar userstr = JSON.stringify(user);

4.5 JAVA处理JSON框架
- 框架
- Hutool工具
- Gson google提供包
- fastJson 阿里巴巴包
- Jackson Spring提供,默认
- json.org和net.json等
- 利用Hutool工具传输JSON
-
不用记,用时打开胡图工具搜
-
步骤
java// 创建JSON对象 JSONObject jsonObject = new JSONObject(); // 设置JSON对象的属性和属性值 jsonObject.set("name", "张三"); jsonObject.set("age", 35); // 将JSON对象转换成字符串(在数据交互时传输的是字符串) String jsonStr = JSONUtil.toJsonStr(jsonObject); out.print(jsonStr);
javascriptvar xhttp; function dianji() { xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = end; xhttp.open("GET", "HutoolServlet", true); xhttp.send(); } function end() { if(xhttp.readyState == 4 && xhttp.status == 200) { var returnData = xhttp.responseText; //{"name":"张三","age":35} //将获取到的字符串转换成JSON对象 var jsonObj = JSON.parse(returnData); //{name: "张三", age: 35} var myspan = document.getElementById("myspan"); myspan.innerHTML = jsonObj.name + "->" +jsonObj.age; } }
-
5. JSON、XML、HTML优缺点
5.1 JSON
- 优点
- 作为一种数据传输格式,更加灵巧
- JSON 不需要从服务器端发送含有特定内容类型的首部信息
- 内容简单,数据量小
- 缺点
- 语法过于严谨
- 代码不易读
5.2 HTML
- HTML 由一些普通文本组成。
- 如果服务器通过 XMLHttpRequest 发送 HTML, 文本将存储在 responseText 属性中
- 不用从 responseText 属性中读取数据,可以直接将它插入到页面中
- 插入 HTML 代码最简单的方法是更新这个元素的 innerHTML 属性
- 优点
- 从服务器端发送的 HTML 代码在浏览器端不需要用 JavaScript 进行解析
- HTML 的可读性好
- HTML 代码块与 innerHTML 属性搭配,效率高
- 缺点
- HTML 不合适通过 AJAX 更新一篇文档的多个部分
- innerHTML 并非 DOM 标准
5.3 XML
- 优点
- XML 是一种通用的数据格式
- 不必把数据强加到已定义好的格式中,而是要为数据自定义合适的标记
- 利用 DOM 可以完全掌控文档
- 缺点
- 如果文档来自于服务器,就必须得保证文档含有正确的首部信息
- 若文档类型不正确,那么 responseXML 的值将是空的
- 当浏览器接收到长的 XML 文件后, DOM 解析可能会很复杂
5.4 JSON与XML对比
-
相同点
- JSON 和 XML 均可用于从 web 服务器接收数据
- JSON 和 XML 都是"自描述的"(人类可读的)
- JSON 和 XML 都是分级的(值中有值)
- JSON 和 XML 都能被大量编程语言解析和使用
- JSON 和 XML 都能被 XMLHttpRequest 读取
-
不同点
XML 必须使用 XML 解析器进行解析,而 JSON 可通过标准的 JavaScript 函数进行解析
- JSON 不使用标签
- JSON 更短
- JSON 的读写速度更快
- JSON 可使用数组
-
对比小结
- 若应用程序不需要与其他应用程序共享数据的时候, 使用 HTML 片段来返回数据时最简单的
- 如果数据需要重用, JSON 文件是个不错的选择, 其在性能和文件大小方面有优势,目前用最多数据交换格式
- 当使用WebService数据交换, XML 文档是首选, 因为 XML 是 webService 服务领域的 "世界语"
- 建议新开发接口使用json进行数据交换
6. XML
6.1 XML简介
- XML(eXtensible Markup Language):可扩展标记语言
- XML用来传输和存储数据,HTML用来展现数据
- XML标签没有被预定义,需要用自己定义
- XML具有自我描述性
- XML 是 W3C 的推荐标准
- XML的用途
- XML 把数据从 HTML 分离:通过 XML,数据能够存储在独立的 XML 文件中
- XML 简化数据共享:XML 数据以纯文本格式进行存储,是一种独立于软件和硬件的数据存储方法
- XML 简化数据传输:通过 XML,可以在不兼容的系统之间轻松地交换数据
- XML 简化平台的变更:XML 数据以文本格式存储。这使得 XML 在不损失数据的情况下,更容易扩展或升级到新的操作系统、新应用程序或新的浏览器
- XML 用于创建新的 Internet 语言
- XHTML - 最新的 HTML 版本
- WSDL - 用于描述可用的 web service
- WAP 和 WML - 用于手持设备的标记语言
- RSS - 用于 RSS feed 的语言
- RDF 和 OWL - 用于描述资源和本体
- SMIL - 用于描述针针对 web 的多媒体
- XML的应用范围
- 在AJAX中使用XML回传数据,如:text/xml
- 使用XML存储少量的数据,如:数据临时存储在xml中,例如游戏中的装备
- 使用XML作为表现层
- 使用XML作为数据传输的中间格式,如:数据传输的接口
- 使用XML作为配置文件,如:web.xml
6.2 XML 与 HTML 的差异
- XML 不是 HTML 的替代
- XML 被设计为传输和存储数据,其焦点是数据的内容
- HTML 被设计用来显示数据,其焦点是数据的外观
- HTML 旨在显示信息,而 XML 旨在传输信息
6.3 XML声明
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- XML声明一般是XML文档的第一行
- 组成
- version :文档符合XML1.0规范
- encoding :文档字符编码,默认为"UTF-8"
- standalone:文档定义是否在一个文件内(yes/no)
- XML语法规则
- 必须有根元素
- 标签区分大小写
- 标签必须是封闭的
- 标签嵌套格式要正确
- 属性
-
XML 元素可以在开始标签中包含属性,类似 HTML
-
属性通常提供不属于数据组成部分的信息
-
属性值须加引号
-
避免 XML 属性
尽量使用元素来描述数据,仅仅使用属性来提供与数据无关的信息
- 属性无法包含多重的值(元素可以)
- 属性无法描述树结构(元素可以)
- 属性不易扩展(为未来的变化)
- 属性难以阅读和维护
-
6.4 元素
- XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分
- 元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性
- 元素命名规范
- 名称中可以包含字母、数字或者其它字符
- 名称不能以数字和"_"(下划线)开头
- 不能以XML/xml/Xml/...开头
- 名称中不能含空格
- 名称中不能含冒号(注:冒号留给命名空间使用)
6.5 字符数据的分类
- PCDATA:将由解析器解析
- CDATA:不会由解析器解析,显示一些已经是xml保留字的字符
7. DTD验证
7.1 DTD简介
- DTD(Document Type Definition):文档类型定义,定义 XML 文档的合法构建模块
- DTD使用一系列合法的元素来定义文档的结构
- DTD文档包含
- 元素(ELEMENT)的定义规则
- 元素之间的关系规则
- 属性(ATTLIST)的定义规则
- 应用程序可以使用一个标准DTD校验从外部世界接受来的XML数据是否有效
- 可以使用DTD校验自己的XML数据
7.2 DOCTYPE 声明
- 内部的 DOCTYPE 声明:
- 外部文档声明:
7.3 元素、属性定义
- 元素定义:<!ELEMENT NAME CONTENT>
- 属性定义:<!ATTLIST 元素名称 属性名称 属性类型 属性特点>
- 属性特点
8. Schema验证
8.1 命名空间
- 目的:避免元素名冲突
- 语法定义
- 元素和属性都可以应用命名空间
- 使用URL作为XML的Namespaces
- xmlns:[prefix]="URL"
- 命名冲突
- XML的元素名是不固定的
- 当两个不同的文档使用同样的名称描述两个不同类型的元素时,就会发生命名冲突
- 使用命名空间属性
8.2 Schema简介
- XML Schema 是基于 XML 的 DTD 替代者
- XML Schema 可描述 XML 文档的结构
- 定义 XML 文档的合法构建模
- web.xml使用的是Schema约束
8.3 DTD与Schema的对比

8.4 引用SCHEMA
- 未指定目标命名空间
- 根元素通过noNamespaceSchemaLocation属性指定SCHEMA文件的位置
- 根元素通过noNamespaceSchemaLocation属性指定SCHEMA文件的位置
- 指定了目标命名空间
- 根元素通过schemaLocation属性指定SCHEMA文件的位置
- 根元素通过schemaLocation属性指定SCHEMA文件的位置
8.5 complexType与simpleType区别
- simpleType类型的元素中不能包含元素或者属性
- 当需要声明一个元素的子元素和/或属性时,用complexType
- 当需要基于内置的基本数据类型定义一个新的数据类型时,用simpleType
9. XStream
9.1 XStream介绍
- XStream是Java类库,用来将对象序列化成XML (JSON)或反序列化为对象
- XStream在运行时使用Java反射机制对要进行序列化的对象树的结构进行探索,并不需要对对象作出修改
- XStream可以序列化内部字段,包括private和final字段,并且支持非公开类以及内部类
- Xstream是一种OXMapping(映射) 技术,是用来处理XML文件序列化的框架
9.2 xstream使用
-
用处:将xml与对象间相互转换,虽然json也可以转换,但是太繁琐,舍弃
-
实例化XStream:XStream xstream = new XStream();
-
方法
- xstream.alias(String elementName, Class cls):为XML元素名称的自定义类名创建别名
javastream.alias("student", Student.class);//表明给Student全类名设置别名
- xstream.toXML(Object obj):将对象转换为XML
-
创建XStream对象
javaXStream stream = new XStream();
-
给全类名设置别名
javastream.alias("student", Student.class);
-
将对象转换成xml
javaString xml = stream.toXML(stu);
-
java@Test void objToXml() { // 创建XStream对象 XStream stream = new XStream(); Student stu = new Student("1001", "张三", new Clazz("01", "软件工程")); // 给Student全类名设置别名 stream.alias("student", Student.class); // 将对象转换成xml String xml = stream.toXML(stu); System.out.println(xml); }
- xstream.fromXML(String xml):将XML转换为对象
-
创建XStream对象
javaXStream stream = new XStream();
-
标明xml中的别名对应哪个类
javastream.alias("student", Student.class);
-
标明接受哪个类型的类
- 必须设置允许的类型,否则无法转换且会报错
javaClass<?>[] cla = new Class[] {Student.class};
-
标明允许哪个类行的类被转化
javastream.allowTypes(cla);
-
将xml转化成对象
javaStudent stu = (Student) stream.fromXML(xml);
-
java@Test void xmlToObj() { String xml = "<student>\r\n" + " <sId>1001</sId>\r\n" + " <sName>张三</sName>\r\n" + " <clazz>\r\n" + " <cId>01</cId>\r\n" + " <cName>软件工程</cName>\r\n" + " </clazz>\r\n" + "</student>"; // 创建Xstream对象 XStream stream = new XStream(); // 先标明xml中的别名是哪个类的 stream.alias("student", Student.class); // 表明接受哪个类型的类 Class<?>[] cla = new Class[] {Student.class}; // 表明允许哪个类型的类被转化 stream.allowTypes(cla); // 将xml转化成对象 Student stu = (Student) stream.fromXML(xml); System.out.println(stu); }
- xstream.allowType(new Class<?>[ ]):允许特定的类型在序列化或反序列化过程中被处理
javastream.allowTypes(new Class[] {Student.class});//表明允许Student类被转化
java// 表明接受哪个类型的类 Class<?>[] cla = new Class[] {Student.class}; // 表明允许哪个类型的类被转化 stream.allowTypes(cla);
9.3 huTool使用
- 用处
- 将JSON与对象进行相互转换(bean类中必须提供set方法)
- 将JSON与XML进行相互转换
- 方法
-
JSON与对象互转
- JSONUtil . toJsonPerttyStr(Object o):将对象转换成JSON
java@Test void objToJson() { Student s1 = new Student("1001", "张三", new Clazz("01", "软件工程")); // 将对象转换成JSON String json = JSONUtil.toJsonPrettyStr(s1); System.out.println(json); }
- JSONUtil . toBean(String json , Class cls):将JSON转成对象
java@Test void jsonToObj() { String json = "{\r\n" + " \"sId\": \"1001\",\r\n" + " \"sName\": \"张三\",\r\n" + " \"clazz\": {\r\n" + " \"cId\": \"01\",\r\n" + " \"cName\": \"软件工程\"\r\n" + " }\r\n" + "}"; // 将JSON转换成对象 Student s1 = JSONUtil.toBean(json, Student.class); System.out.println(s1); }
-
JSON与XML互转
- JSONUtil.parseFromXml(String str):将xml转换成JSON
java@Test void xmlToJSON() { String xml = "<sfzh>123</sfzh>" + "<sfz>456</sfz>" + "<name>aa</name>" + "<gender>1</gender>"; // 将xml转换成JSON JSONObject json = JSONUtil.parseFromXml(xml); System.out.println(json.get("sfzh")); // 123 System.out.println(json.get("name")); // aa }
- JSONUtil.toXmlStr(JSONObject json):将JSON转换成xml
java@Test void jsonToXml() { JSONObject json = JSONUtil.createObj() .set("aaa", "你好") .set("键2", "test"); // 将JSON转换为xml String xml = JSONUtil.toXmlStr(json); System.out.println(xml); // <aaa>你好</aaa><键2>test</键2> }
-
10. XML解析
浏览器可以直接解析XML
10.1 XML解析方式
10.1.1 DOM
- DOM:Document Object Model
- DOM解析一次将文档加载入内存建立树型模型
- 如果XML文档过大,会出现内存溢出的问题
- 优缺点
- 优点:方便进行增删改操作
- 缺点:速度慢,占用资源多,解析中小XML文档
10.1.2 SAX
- SAX:Simple API for XML
- 速度快,占用资源少,解析大XML文档
- 根据事件驱动一行一行进行加载解析的
- 优缺点
- 优点:不会出现内存溢出的问题,且方便查询
- 缺点:不能进行增删改操作
10.1.3 DOM和SAX对比

10.2 三种XML解析器
10.2.1 XML解析器分类
解析器是根据解析技术开发的工具,解析技术记住DOM和SAX即可
- sun开发的jaxp(不依赖第三方)
- dom4j (最为常用)
- jdom (使用较少)
10.2.2 读写XML
- 写XML
- 创建一个document
- 组装xml文档结构
- 格式良好的写在一个位置(outputStream)
- 读XML
- 创建一个解析XML的解析器
- 加载外部xml(inputStream)
- 循环、拆解、获取项目节点,得到想要的节点数据
10.2.3 JAXP
- JAXP是使用JavaAPI对XML进行处理的一种规范,它提供接口来操作SAX和DOM
- JAXP的API已经包含在JDK中,包含了三个包
- org.w3c.dom:W3C推荐的用于XML操作的标准文档对象模型的接口
- org.xml.sax:用于对XML进行语法分析的事件驱动的XML简单API(SAX)
- Javax.xml.parsers:解析器工厂工具,程序员获得并配置特殊的语法分析器
10.2.4 JDOM
-
JDOM是一个开源项目,它基于树型结构,利用JAVA语言的诸多特性(方法重载、集合概念以及映射),把SAX和DOM的功能有效地结合起来,实现对XML文档解析、生成、序列化等多种操作
-
所需jar包:jdom-1.1.3.jar
-
读写XML
-
写XML
- 创建元素
javaElement name= new Element("name");
- 创建属性,并为元素添加属性
javaname.setAttribute(new Attribute("id", "100"));
- 组装元素数据并加载到一个文档
javaDocument doc = new Document(name);
- 设置格式斌写入到一个文件中
javaXMLOutputter out = new XMLOutputter(); out.getFormat().setEncoding("utf-8"); out.output(doc, new FileOutputStream("d:/jdomaddress.xml"));
java@Test public void jdomWrite() throws FileNotFoundException, IOException { // 创建元素写xml文件 Element addresslist = new Element("addresslist"); Element name = new Element("name"); Element email = new Element("email"); name.setText("lisi"); email.setText("[email protected]"); // name.setAttribute("id", "100"); // 创建添加属性 Attribute attr = new Attribute("id", "100"); name.setAttribute(attr); addresslist.addContent(name); addresslist.addContent(email); // 组装元素数据,组装好数据要加到文档中, Document doc = new Document(addresslist); // 写到一个文件中 XMLOutputter out = new XMLOutputter(); out.getFormat().setEncoding("utf-8"); out.output(doc, new FileOutputStream("d:/jdomaddress.xml")); }
-
读XML
- 获取读取对象
javaSAXBuilder sax = new SAXBuilder();
- 加载文件地址
javaDocument doc = sax.build(new File("d:/jdomaddress.xml"));
- 获取根节点
javaElement root = doc.getRootElement();
- 获取节点内容
javaString ntxt = root.getChildText("name");
java@Test public void jdomRead() throws JDOMException, IOException { // 读xml,首先有个读取对象,加载文件地址 SAXBuilder sax = new SAXBuilder(); // 读进来xml肯定是一个文档 Document doc = sax.build(new File("d:/jdomaddress.xml")); Element root = doc.getRootElement(); // 获取根节点 // 直接获取子节点内容 String ntxt = root.getChildText("name"); String etxt = root.getChildText("email"); System.out.println(ntxt); System.out.println(etxt); }
-
10.2.5 DOM4j
-
所需jar包:dom4j-1.6.1.jar
-
读写XML
-
写XML
- 创建文档对象
javaDocument doc = DocumentHelper.createDocument();
- 文档中增加根节点
javaElement addresslist = doc.addElement("addresslist");
- 根节点中增加子节点
javaElement name = addresslist.addElement("name");
- 节点增加内容
javaname.setText("taobinbin");
- 设置xml格式
javaOutputFormat of = OutputFormat.createPrettyPrint(); of.setEncoding("utf-8");
- 写入文件,输出对象,输出流
javaXMLWriter writer = new XMLWriter(new FileOutputStream("d:/dom4j.xml"),of); writer.write(doc);
java@Test public void writeDom4j() throws IOException { // 创建元素,需要创建文档,逻辑和jdom不一样 // 1. 创建一个文档,使用帮助类创建一个文档对象 Document doc = DocumentHelper.createDocument(); // 2. 文档中需要增加根节点 Element addresslist = doc.addElement("addresslist"); // 3. 根几点需要增加子节点 Element name = addresslist.addElement("name"); Element email = addresslist.addElement("email"); // 4. 节点增加内容 name.setText("taobinbin"); email.setText("[email protected]"); name.addAttribute("id", "111"); // 输出前,一般都会设置xml格式,良好格式输出 OutputFormat of = OutputFormat.createPrettyPrint(); of.setEncoding("utf-8"); // 5. 写到一个文件中去,输出对象,输出流 XMLWriter writer = new XMLWriter(new FileOutputStream("d:/dom4j.xml"), of); // 创建了输出文件 // doc没有放到输出中 writer.write(doc); writer.close(); }
-
读XML
- 创建解析器
javaSAXReader sax = new SAXReader();
- 读取xml文件
javaDocument doc = sax.read(new File("d:/dom4j.xml"));
- 获取根节点
javaElement root = doc.getRootElement();
- 遍历根节点下的子节点,并输出节点内容
javaList<Element> lst = root.elements(); for(Element e:lst){ System.out.println(e.getText()); }
java@Test public void readDom4j() throws DocumentException { // 读文件,有一个解析器 SAXReader sax = new SAXReader(); // 读取那个文件 File f = new File("d:/dom4j.xml"); // 读完成后肯定是一个dom文档 Document doc = sax.read(f); // 获取到根节点,一层一层的去找,或者通过tag直接定位某一个xml元素节点 Element root = doc.getRootElement(); System.out.println(root.elements().size()); List<Element> lst = root.elements(); for (Element e : lst) { System.out.println(e.getText()); } }
-
11. jQuery框架
11.1 jQuery简介
- jQuery库可以通过一行简单的标记被添加到网页中
- 特性
- HTML 元素选取
- HTML 元素操作
- CSS 操作
- HTML 事件函数
- JavaScript 特效和动画
- HTML DOM 遍历和修改
- AJAX
- Utilities
- JavaScript 库作用
- JavaScript 库封装了很多预定义的对象和实用函数
- 能帮助使用者建立有高难度交互的 Web2.0 特性的富客户端页面
- 兼容各大浏览器
- jQuery框架介绍
- jQuery 是一个免费、开源的轻量级JavaScript 库,极大地简化了 JavaScript 编程
- 兼容CSS3,还兼容各种浏览器,使用户能更方便地处理HTML documents、events、实现动画效果
- 方便地为网站提供AJAX交互
- jQuery使用方式
-
下载jQuery包
- 加min代表压缩版,不加min代表完整版,如:jquery-3.6.3.js
-
使用
javascript<script src="js/jquery-3.6.3.js"></script>
-
11.2 jQuery 对象
11.2.1 jQuery 对象
- jQuery 对象:通过jQuery包装DOM对象后产生的对象
- jQuery 对象无法使用 DOM 对象的任何方法, 同样 DOM 对象也不能使用 jQuery 里的任何方法
11.2.2 jQuery 对象转 DOM 对象
- jQuery 对象不能使用 DOM 中的方法
- jQuery转Dom
-
通过 [index] 的方法
- jQuery 对象是一个数组对象, 可以通过 [index] 的方法得到对应的 DOM对象
javascript$(document).ready(function() { var $mydiv = $("#mydiv"); // 将jquery对象转换成js对象 // 方法一:通过[index]转换 var mydiv1 = $mydiv[0]; console.log(mydiv1.innerHTML); });
-
jQuery 中的get(index)
- jQuery 中的 get(index) 方法得到相应的 DOM 对象
javascript$(document).ready(function() { var $mydiv = $("#mydiv"); // 将jquery对象转换成js对象 // 方法二:通过jquery的get方法转换 var mydiv2 = $mydiv.get(0); console.log(mydiv2.innerHTML); });
-
11.2.3 DOM 对象转 jQuery 对象
-
DOM对象不能使用jQuery 中的方法
-
Dom转jQuery
- $()
javascript$(document).ready(function() { var mydiv = document.getElementById("mydiv"); // js对象转换为jquery对象 var $mydiv = $(mydiv); console.log($mydiv.html()); });
- jQuery 对象就是通过 jQuery 包装 DOM 对象后产生的对象
11.3 jQuery语法及事件
11.3.1 语法
- 语法:
$(selector).action()
- selector:查询或查找 HTML 元素
- action() :执行对元素的操作
11.3.2 事件
- 事件处理程序指的是当 HTML 中发生某些事件时所调用的方法
11.3.2.1 事件原则
- 把所有 jQuery 代码置于事件处理函数中
- 把所有事件处理函数置于文档就绪事件处理器中
- 把 jQuery 代码置于单独的 .js 文件中
- 如果存在名称冲突,则重命名 jQuery 库
11.3.2.2 ready()事件
-
在页面加载完毕后, 浏览器会通过 JavaScript 为 DOM 元素添加事件
-
常规
- window.onload
- 只能写一个
javascriptwindow.onload=function() {}
-
jQuery
- $(document).reday()
- 简写: $().ready()
- 可以写多个
javascript$(document).ready(function(){});
-
对比
11.3.2.2 hide()事件
- 隐藏html元素
- 示例
$(this)
.hide() - 隐藏当前元素$("p")
.hide() - 隐藏所有段落$(".test")
.hide() - 隐藏所有 class="test" 的所有元素$("#test")
.hide() - 隐藏所有 id="test" 的元素
11.3.2.3 事件的绑定和移除
-
bind()事件:为被选元素添加一个或多个事件处理程序
- 语法:
$(selector).bind(event,data,function)
- 参数
- 替代语法:
$(selector).bind({event:function, event:function, ...})
javascript$(document).ready(function() { $("button").on("click", function() { $("p").slideToggle(); }); });
- 语法:
-
unbind()事件:移除被选元素的事件处理程序
- 语法:
$(selector).unbind(event,function)
- 参数
javascript$(document).ready(function() { $("p").click(function() { $(this).slideToggle(); }); $("button").click(function() { $("p").off("click"); }); });
- 语法:
-
one()事件:被选元素附加一个或多个事件处理程序
- 使用 one() 方法时,每个元素只能运行一次事件处理器函数
- 语法:
$(selector).one(event,data,function)
- 参数
javascript$(document).ready(function() { $("p").one("click", function() { $(this).animate({ fontSize: "+=6px" }); }); });
11.4 jQuery选择器
- 选择器允许对 DOM 元素组或单个 DOM 节点进行操作
- 分类
- 基本选择器:通过元素 id, class 和标记名来查找 DOM 元素
- 属性选择器:使用 XPath 表达式来选择带有给定属性的元素
- 元素选择器:使用 CSS 选择器来选取 HTML 元素
- 层次选择器
- 过滤选择器
- 基本选择器:通过元素 id, class 和标记名来查找 DOM 元素
11.5 jQuery中DOM操作
11.5.1 DOM
- DOM(Document Object Model):文档对象模型
- 一种与浏览器, 平台, 语言无关的接口, 使用该接口可以轻松地访问页面中所有的标准组件
11.5.2 DOM操作分类
- DOM Core
- DOM Core 并不专属于 JavaScript, 任何一种支持 DOM 的程序设计语言都可以使用它
- 它的用途并非仅限于处理网页, 也可以用来处理任何一种是用标记语言编写出来的文档, 例如: XML
- HTML DOM
- 使用 JavaScript 和 DOM 为 HTML 文件编写脚本时, 有许多专属于 HTML-DOM 的属性
- CSS-DOM
- 针对于 CSS 操作, 在 JavaScript 中, CSS-DOM 主要用于获取和设置 style 对象的各种属性
11.5.3 获得内容
带参是设置内容,不带参数是获取内容
-
text():设置或返回所选元素的文本内容
- 相当于innerText
javascript$("#btn1").click(function() { $("#test1").text("Hello world!"); });
-
html():设置或返回所选元素的内容(包括 HTML 标记)
- 相当于innerHTML
javascript$("#btn2").click(function() { $("#test2").html("<b>Hello world!</b>"); });
-
val():设置或返回表单字段的值
- 相当于value
javascript$("#btn3").click(function() { $("#test3").val("Dolly Duck"); });
11.5.4 获取属性
- attr():用于获取属性值
- 语法:
$(selector).attr("属性名","属性值")
javascript
$(document).ready(function() {
$("button").click(function() {
$("#w3s").attr("href", "http://www.baidu.com");
});
});
11.6 jQuery效果
11.6.1 jQuery隐藏和显示
-
hide():隐藏被选的元素
$(selector).hide(speed,callback)
- speed:规定元素从可见到隐藏的速度
- 参数值
- 毫秒 (如: 1500)
- "slow"
- "normal"
- "fast"
- 参数值
- callback:函数执行完之后,要执行的函数
javascript$("p").hide(1000);
-
show():显示被选的元素
$(selector).show(speed,callback)
javascript$("p").show();
-
toggle():对被选元素进行隐藏和显示的切换
$(selector).toggle(speed,callback,switch)
- switch:布尔值。规定 toggle 是否隐藏或显示所有被选元素
javascript$("p").toggle();
11.6.2 jQUery滑动
-
slideDown():向下滑动元素
$(selector).slideDown(speed,callback)
javascript$(document).ready(function() { $(".flip").click(function() { $(".panel").slideDown("slow"); }); });
-
slideUp():向上滑动元素
$(selector).slideUp(speed,callback)
javascript$(document).ready(function() { $(".flip").click(function() { $(".panel").slideUp("slow"); }); });
-
slideToggle():切换元素滑动的方向
$(selector).slideToggle(speed,callback)
javascript$(document).ready(function() { $(".flip").click(function() { $(".panel").slideToggle("slow"); }); });
11.6.3 Callback函数
-
Callback 函数在当前动画 100% 完成之后执行,类似于回调函数
-
$(selector).hide(speed,callback)
- callback 参数是一个在 hide 操作完成后被执行的函数
javascript$(document).ready(function() { $("button").click(function() { $("p").hide(1000, function() { alert("The paragraph is now hidden"); }); }); });
11.7 jQuery HTML
11.7.1 DOM
- DOM(Document Object Model):文档对象模型
- 一种与浏览器, 平台, 语言无关的接口, 使用该接口可以轻松地访问页面中所有的标准组件
11.7.2 jQuery获取与设置内容
带参是设置内容,不带参数是获取内容
-
获取内容
- text():设置或返回所选元素的文本内容
- 相当于innerText
javascript$("#test1").text("Hello world!");
- html():设置或返回所选元素的内容(包括 HTML 标记)
- 相当于innerHTML
javascript$("#test2").html("<b>Hello world!</b>");
- val():设置或返回表单字段的值
- 相当于value
javascript$("#test3").val("Dolly Duck");
- text():设置或返回所选元素的文本内容
-
获取属性
- attr():用于获取属性值
$(selector).attr("属性名","属性值")
javascript$("#w3s").attr("href", "http://www.baidu.com");
- attr():用于获取属性值
11.7.3 jQuery添加元素内容
-
append():在被选元素的结尾内部插入内容
- append和appendChild是有区别的,js中appendChild只能添加对象,而jQuery中append既能添加html代码也能添加对象
- 在被选元素的内部进行操作,如被选元素是div,则在div区域内部进行插入
- 语法:
$(selector).append(content)
- content:规定要插入的内容(可包含 HTML 标签)
javascript$("p").append(" <b>Appended text</b>.");
-
prepend():在被选元素的开头内部插入内容
- 在被选元素的内部进行操作,如被选元素是div,则在div区域内部进行插入
- 语法:
$(selector).prepend(content)
javascript$("ol").prepend("<li>Prepended item</li>");
-
after():在被选元素之后外部插入内容
- 在被选元素的外部进行操作,如被选元素是div,则在div区域外部进行插入
- 语法:
$(selector).after(content)
javascript$("p").before("<b>Before</b>");
-
before():在被选元素之前外部插入内容
- 在被选元素的外部进行操作,如被选元素是div,则在div区域外部进行插入
- 语法:
$(selector).before(content)
javascript$("p").after("<i>After</i>");
11.7.4 jQuery删除元素内容
-
remove连同当前元素和所有子元素都删除了,而empty只删除了子元素,当前元素并没有删除
-
remove():删除被选元素(及其子元素)
- remove() 方法移除被选元素,包括所有文本和子节点
$(selector).remove()
javascript$("#div1").remove();
-
empty():从被选元素中删除子元素
- 相当于innerHTML=""
- empty() 方法从被选元素移除所有内容,包括所有文本和子节点
$(selector).empty()
javascript$("#div1").empty();
11.7.5 jQuery CSS类
-
addClass() :向被选元素添加一个或多个类(样式)
javascript$("div").addClass("important");
-
removeClass():从被选元素删除一个或多个类(样式)
javascript$("h1,h2,p").removeClass("blue");
-
toggleClass() :对被选元素进行添加/删除类(样式)的切换操作
javascript$("h1,h2,p").toggleClass("blue");
-
css():设置或返回样式属性
javascript$("p").css("background-color")
11.8 jQuery遍历
11.8.1 jQuery 祖先
方法 | 描述 | 特点 |
---|---|---|
parent() |
返回被选元素的直接父元素 | 只会向上一级对 DOM 树进行遍历 |
parents() |
返回被选元素的所有祖先元素 | 会一路向上直到文档的根元素 (<html> ) |
parentsUntil() |
返回介于两个给定元素之间的所有祖先元素 | 返回指定元素之间的所有祖先元素 |
javascript
// 获取直接父元素
$("span").parent();
// 获取所有祖先元素
$("span").parents();
// 获取介于 span 和 div 之间的所有祖先元素
$("span").parentsUntil("div");
11.8.2 jQuery 后代
方法 | 描述 | 遍历深度 | 返回内容 |
---|---|---|---|
children() |
返回被选元素的所有直接子元素 | 仅下一级 | 直接子元素 |
find() |
返回被选元素的所有后代元素 | 所有后代层级 | 所有后代元素 |
javascript
// 假设有一个 HTML 结构如下:
// <div id="parent">
// <p>Paragraph 1</p>
// <p>Paragraph 2</p>
// <span>Span 1</span>
// </div>
$("#parent").children().css("color", "red");
$("#parent").find("p").css("color", "blue");
11.8.3 jQuery 同胞
方法 | 描述 |
---|---|
siblings() | 返回被选元素的所有同级元素 |
next() | 返回被选元素的下一个同级元素(一个) |
nextAll() | 返回被选元素的所有后续同级元素(多个) |
nextUntil() | 返回介于两个给定参数之间的所有后续同级元素,不包括给定的参数 |
prev() | 返回被选元素的上一个同级元素(一个) |
prevAll() | 返回被选元素的所有前驱同级元素(多个) |
prevUntil() | 返回介于两个给定参数之间的所有前驱同级元素,不包括给定的参数 |
11.8.4 jQuery 过滤
方法 | 描述 | 示例 |
---|---|---|
first() |
返回被选元素的首个元素 | $("div").first().css("background-color", "yellow"); |
last() |
返回被选元素的最后一个元素 | $("div").last().css("background-color", "green"); |
eq() |
返回被选元素中带有指定索引号的元素 | $("div").eq(2).css("background-color", "blue"); |
filter() |
返回匹配定义的标准的元素 | $("div").filter(".highlight").css("background-color", "red"); |
not() |
返回不匹配标准的所有元素 | $("div").not(".highlight").css("background-color", "orange"); |
11.9 jQuery Ajax
11.9.1 load()
-
load() 方法从服务器加载数据,并把返回的数据放入页面的被选元素中
-
语法:
$(selector).load(URL,data,callback);
- url (String) :请求的HTML页的URL地址
- data (Map) :(可选参数) 发送至服务器的 key/value 数据(json格式)
- callback (Callback):(可选参数) 请求完成时(不需要success)的回调函数
- function(response,status,xhr){}
- response - 包含来自请求的结果数据
- status - 包含请求的状态("success", "notmodified", "error", "timeout" 或 "parsererror")
- xhr - 包含 XMLHttpRequest 对象
- function(response,status,xhr){}
-
默认使用 GET 方式来传递的,如果[data]参数有传递数据进去,就会自动转换为POST方式的
javascript$("button").click(function() { //将LoadServlet响应的数据加载到id为mydiv的区域 $("#mydiv").load("LoadServlet"); });
11.9.2 get()
-
$.get()
方法通过 HTTP GET 请求从服务器上请求数据 -
语法:
$(selector).get(url,data,callback,dataType)
-
callback (Function) : (可选) 载入成功时回调函数(只有当Response的返回状态是success才是调用该方法)
- url (String):发送请求的URL地址
- data (Map) :(可选参数) 发送至服务器的 key/value 数据(json格式)
- callback (Callback):(可选参数) 请求完成时(success)的回调函数
- function(response,status,xhr){}
- response:包含来自请求的结果数据
- status:包含请求的状态("success", "notmodified", "error", "timeout" 或 "parsererror")
- xhr:包含 XMLHttpRequest 对象
- function(response,status,xhr){}
- dataType:规定预计的服务器响应的数据类型
- 类型:"xml"、"html"、"text"、"script"、"json"、"jsonp"
-
等价于
javascript$.ajax({ url: url, data: data, success: success, dataType: dataType });
javascript$(function() { var name = $("#uname").val(); $("#mybtn").click(function() { $.get("AjaxServletText?uname=" + name, function(result) { $("#myspan").html(result); }); }); });
11.9.3 post()
-
$.post()
方法通过 HTTP POST 请求从服务器上请求数据 -
语法:
$(selector).get(url,data,callback,dataType)
- url (String):发送请求的URL地址
- data (Map) :(可选参数) 发送至服务器的 key/value 数据(json格式)
- callback (Callback):(可选参数) 请求完成时(success)的回调函数
- callback (Function) : (可选) 载入成功时回调函数(只有当Response的返回状态是success才是调用该方法)
- dataType:规定预计的服务器响应的数据类型
javascript$(function() { var name = $("#uname").val(); $("#mybtn").click(function() { $.post("AjaxServletText", {"uname": name}, function(result) { $("#myspan").html(result); }); }); });
11.9.4 getScript()
-
jQuery.getScript( url, [callback] ) : 通过 GET 方式请求载入并执行一个 JavaScript 文件,可以跨域调用JavaScript 文件
- url (String) :待载入 JS 文件地址
- callback (Function) :(可选) 成功载入后回调函数
javascript// 假设有一个外部的JavaScript文件名为externalScript.js $(document).ready(function(){ // 当页面加载完成后,点击按钮时载入并执行externalScript.js $("button#loadScript").click(function(){ $.getScript("path/to/externalScript.js", function(){ console.log("Script loaded and executed."); // externalScript.js 已被加载并执行 // 如果externalScript.js中有函数或变量定义,现在可以调用它们 }); }); });
11.9.5 getJSON()
-
jQuery.getJSON(url,[callback])函数用于通过get请求载入JSON数据
- url (String) :待载入 JSON 文件地址
- callback (Function) :(可选) 成功载入后回调函数
javascript$(document).ready(function(){ // 当页面加载完成之后,点击按钮时发起请求获取JSON数据 $("button#getJsonData").click(function(){ $.getJSON("path/to/data.json", function(data){ // data 参数包含了服务器返回的JSON对象 console.log("JSON Data: "); console.log(data); // 示例:遍历返回的JSON数组,并显示每个元素的内容 $.each(data, function(index, item){ console.log("Item " + index + ": " + item.name); // 假设JSON对象中的每个元素都有一个name属性 }); }).fail(function(jqxhr, textStatus, error) { var err = textStatus + ", " + error; console.error("Request Failed: " + err); }); }); });
12. Ajax.07 Node.js
12.1 Node.js简介
-
什么是Node.js?
Node.js 可以理解为是一个使用 JavaScript 编写后端代码的工具或框架
- Node.js是运行在服务端的 JavaScript
- Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台
- Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎
- Node采用Google开发的V8引擎运行js代码,使用事件驱动、非阻塞和异步I/O模型等技术来提高性能,可优化应用程序的传输量和规模
- Node把JS的易学易用和Unix网络编程的强大结合到了一起
- 核心模块包括文件系统I/O、网络(HTTP、TCP、UDP、DNS、 TLS/SSL等)、二进制数据流、加密算法、数据流等等
-
Node.js的特点
- 单线程和事件驱动架构
- Node.js 使用单线程来处理请求,但通过事件驱动和非阻塞 I/O 操作的特性,使其可以高效地处理大量并发连接,而不会阻塞线程
- 异步和非阻塞 I/O
- 这使得 Node.js 能够处理高并发的请求,非常适合 I/O 密集型应用,如文件读取、数据库操作和网络请求
- 跨平台支持
- Node.js 可以在 Windows、Linux 和 macOS 等多个操作系统上运行
- 庞大的生态系统
- Node.js 拥有一个名为 npm(Node Package Manager)的生态系统,其中有丰富的第三方库和模块,可以用来扩展功能和加速开发
- 单线程和事件驱动架构
-
Node.js的用途
- Node主要用于编写像Web服务器一样的网络应用
- Node是事件驱动的,开发者可以在不使用线程的情况下开发出一个能够承载高并发的服务器
- Node.js允许通过JS和一系列模块来编写服务器端应用和网络 相关的应用
-
Node.js的应用场景
- Web 服务器
- 由于其高效的处理并发请求的能力,Node.js 常被用于构建快速、可扩展的 web 服务器
- 实时应用
- 例如聊天应用、实时协作工具等
- API 服务
- Node.js 很适合用来开发 RESTful API 和 GraphQL 服务
- 命令行工具
- Node.js 还可以用于构建 CLI 工具,利用其易用的库和包管理器进行快速开发
- Web 服务器
12.2 Node.js应用
12.2.1 安装
根据菜鸟教程的 安装指导 进行安装
12.2.2 node目录结构

12.2.3 node应用
- Node.js 本身就内置了一个 HTTP 服务器模块,开发者可以直接使用 Node.js 的 HTTP 模块来创建服务器,处理 HTTP 请求,并生成 Web 页面
- 开发者不需要依赖于外部的 HTTP 服务器软件
- 别的程序,如vue等需要用到node,因为vue等编译时需要用到node,需要依赖node中的第三方jar包
- 应用的组成
- require 指令
- 在 Node.js 中,使用 require 指令来加载和引入模块,引入的模块可以是内置模块,也可以是第三方模块或自定义模块
- 相当于导包,Java中的import
- 创建服务器
- 服务器可以监听客户端的请求,类似于 Apache 、Nginx 等 HTTP 服务器
- Apache 、Nginx 只能运行静态的html,前端页面放在Apache 、Nginx 中,由Apache 、Nginx 调用后台Tmocat中的Java代码
- 接收请求与响应请求
- 服务器很容易创建,客户端可以使用浏览器或终端发送 HTTP 请求,服务器接收请求后返回响应数据
- require 指令
12.2.4 创建node.js应用
-
使用 require 指令来加载和引入模块
- 语法:const module = require('module-name');
- module-name
- 可以是一个文件路径(相对或绝对路径),也可以是一个模块名称,相当于jar包名
- 如果是一个模块名称,Node.js 会自动从 node_modules 目录中查找该模块
- require 指令
- 会返回被加载的模块的导出对象,可以通过该对象来访问模块中定义的属性和方法
- 如果模块中有多个导出对象,则可以使用解构赋值的方式来获取它们
javascript// 使用 require 指令来载入 http 模块,并将实例化的 HTTP 赋值给变量 http var http = require("http");
-
创建服务器
- 使用 http.createServer() 方法创建服务器
- 使用 listen 方法绑定 8888 端口
- 函数通过 request, response 参数来接收和响应数据
javascriptvar http = require('http'); http.createServer(function (request, response) { // 发送 HTTP 头部 // HTTP 状态值: 200 : OK // 内容类型: text/plain response.writeHead(200, {'Content-Type': 'text/plain'}); // 发送响应数据 "Hello World" response.end('Hello World\n'); }).listen(8888); // 终端打印如下信息 console.log('Server running at http://127.0.0.1:8888/');
- 分析Node.js 的 HTTP 服务器
- const http = require('http'):导入 Node.js 内置的 http 模块
- http.createServer((req, res) => { ... }):创建一个新的 HTTP 服务器,每次有请求时都会执行回调函数
- res.writeHead(200, { 'Content-Type': 'text/plain' }):设置响应状态码和内容类型
- res.end('Hello World\n'):结束响应并发送数据
- server.listen(PORT, () => { ... }):监听指定端口并在服务器启动后输出信息
-
接收请求与响应请求
12.2.5 Node.js 的工作机制

12.3 NPM
12.3.1 npm简介
-
简介
node就是写js的工具,相当于jar,npm就是管理包的,相当于maven
- NPM(Node Package Manager)是一个 JavaScript 包管理工具,也是 Node.js 的默认包管理器
- npm相当于 Maven 或 Gradle
- NPM 是 Node.js 自带的包管理工具,因此,通常只需安装 Node.js,NPM 就会自动安装在系统中
-
主要功能
- 包管理
- NPM 可以帮助你安装并管理项目所需的各种第三方库(包)
- 如:可以通过简单的命令来安装、更新、或删除依赖
- 版本管理
- NPM 支持版本控制,允许你锁定某个特定版本的依赖,或根据需求选择最新的版本
- 包发布
- NPM 允许开发者将自己的库发布到 NPM 仓库中,其他开发者可以通过 NPM 下载并使用这些库
- 命令行工具
- NPM 提供了强大的命令行工具,可以用于安装包、运行脚本、初始化项目等多种操作
- 包管理
12.3.2 npm命令
- NPM 提供了很多命令,可以使用 npm help 可查看所有命令
- 安装模块
-
$ npm install <Module Name>
- 如:
$ npm install express
- 安装好之后,express 包就放在了工程目录下的 node_modules 目录中
- 在代码中只需要通过 require('express') 的方式就能获取当前模块
javascriptvar express = require('express');
- 如:
-
全局安装与本地安装
- 本地安装
- 将包安装到 node_modules 目录,并将信息保存到 package.json 的 dependencies 中
npm install express
- 全局安装
- 用于安装命令行工具或需要在多个项目中使用的包
npm install express -g
- 本地安装
-
- 卸载模块:
$ npm uninstall express
- 更新模块:
$ npm update express
- 搜索模块:
$ npm search express
- 从镜像源安装:
npm install 包名 --registry=地址
- 设置镜像源:
npm config set registr y 地址
12.4 CommonJs规范
CommonJS规范的提出,主要是为了弥补当前JavaScript没有模块化标准的缺陷
12.4.1 CommonJS对模块的定义
-
模块引用
-
require():该方法接受模块标识,以此将一个模块引入到当前运行环境中
javascriptvar math = require('math');
-
-
模块定义
-
在运行环境中,提供了exports对象用于导出当前模块的方法或者变量,并且它是唯一的导出的出口
javascriptexports.xxx = function() {};
-
在模块中还存在一个module对象,它代表模块自身,而exports是module的属性
javascriptmodule.exports = {};
-
在Node中一个文件就是一个模块
-
-
模块标识
- 模块标识其实就是模块的名字,也就是传递给require()方法的参数
- 必须是符合驼峰命名法的字符串,或者是以...开头的相对路径、或者绝对路径
12.4.2 Node的模块实现
- 在Node中引入模块,3个步骤
- 路径分析
- 文件定位
- 编译执行
- 在Node中,模块分为三类
- 一类是底层由C++编写的内建模块
- 一类是Node提供的核心模块
- 一类是用户编写的模块,称为文件模块
12.4.3 包Package
- CommonJS的包规范允许我们将一组相关的模块组合到一起,形成一组完整的工具
- 组成
- 包结构
- 包结构:用于组织包中的各种文件
- 包实际上就是一个压缩文件,解压以后还原为目录
- 符合规范的目录,应该包含如下文件
- package.json :描述文件
- bin : 可执行二进制文件
- lib : js代码
- doc : 文档
- test : 单元测试
- 包描述文件
- 包描述文件: 描述包的相关信息,以供外部读取分析
- 它是一个JSON格式的文件 package.json,位于包的根目录下,是包的重要组成部分
- 包结构
13. 跨域处理
13.1 跨域
13.1.1 什么叫跨域?
-
为什么会出现跨域问题?
- 出于浏览器的同源策略限制
-
跨域
- 跨域,是指浏览器不能执行其他网站的脚本
- 是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制
-
跨域场景
- 非跨域
javascripthttp://www.baidu.com/index.jsp http://www.baidu.com/admin/login.jsp
-
跨域
- 协议不同
javascripthttp://www.baidu.com https://www.baidu.com
- 端口不同
javascripthttp://www.caidu.com:8048 http://www.baidu.com(http默认端口80)
-
域名不同
- 主域名不同
javascripthttp://www.taobao.com http://www.baidu.com
- 子域名不同
javascripthttp://www.aa.baidu.com http://www.bb.baidu.com
-
域名
-
域名分类
- 主域名:只能有一个
javascripthttp://www.baidu.com
- 子域名:可以有多个
javascripthttp://www.aa.baidu.com http://www.bb.baidu.com
-
域名证书分类
-
主域名证书
- 阿里云免费
javascripthttp;//www.baidu.com
-
泛域名证书
- 收费
javascripthttp://www.aa.baidu.com
-
-
13.1.2 同源策略
- 同源: 协议、域名、端口号 必须完全相同
- 违背同源策略就是跨域
- 什么是同源策略?
- 同源策略(Sameoriginpolicy)是一种约定,是浏览器最核心也最基本的安全功能
- 同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互
- 同源策略是浏览器的一种安全策略
- Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现
- 同源跨域限制以下行为
- Cookie、LocalStorage 和 IndexDB 无法读取
- DOM 和 JS 对象无法获取
- Ajax请求发送不出去
13.2 jsonp
13.2.1 jsonp跨域
- jsonp跨域其实是JavaScript设计模式中的一种代理模式
- 在html页面中通过相应的标签从不同域名下加载静态资源文件是被浏览器允许的,因此可以借此来实现跨域
- 可以动态的创建script标签,再去请求一个带参网址来实现跨域通信
- 缺点:只能够实现get请求
13.2.2 JSONP
- 什么是JSONP?
- JSONP 是一种无需考虑跨域问题即可传送 JSON 数据的方法
- JSONP:JSON with Padding
- 是一个非官方的跨域解决方案,只支持 get 请求
- JSONP 不使用 XMLHttpRequest 对象,使用
13.2.3 JSONP使用
-
动态的创建一个 script 标签
javascriptvar script = document.createElement("script")
-
设置 script 的 src,设置回调函数
javascriptscript.src = "http://localhost:8080/ajax08_01/JSONPServlet?callback=mydata"; function mydata(obj) { document.getElementById("mydiv").innerHTML = obj.name; }
-
将 script 添加到 body 中
javascriptdocument.body.appendChild(script);
javascript
<script type="text/javascript">
//1. 动态的创建一个 script 标签
var script = document.createElement("script");
//2. 设置 script 的 src,设置回调函数
script.src = "http://localhost:8080/ajax08_01/JSONPServlet?callback=mydata";
function mydata(obj) {
document.getElementById("mydiv").innerHTML = obj.name;
}
//3. 将 script 添加到 body 中
document.body.appendChild(script);
</script>
html
<script type="text/javascript">
function mydata(obj) {
document.getElementById("mydiv").innerHTML = obj.name;
}
</script>
<script src="http://localhost:8080/ajax08_01/JSONPServlet"></script>
13.3 CORS
13.3.1 CORS简介
- CORS(Cross-Origin Resource Sharing):跨域资源共享
- CORS 是官方的跨域解决方案
- 特点
- 不需要在客户端做任何特殊的操作,完全在服务器中进行处理
- 支持 get 和 post 请求
- 工作原理
- 跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些 源站通过浏览器有权限访问哪些资源
- 通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应 以后就会对响应放行
13.3.2 CORS 的使用
-
服务器端的设置
- 服务器端对于CORS的支持,主要是通过设置Access-Control-Allow-Origin来进行的
- 如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问
-
通过 response 来设置响应头
- 只允许特殊路径下的ajax访问:
response .set("Access-Control-Allow-Origin","http://127.0.0.1:3000");
- 所有ajax都允许访问:
response .set("Access-Control-Allow-Origin","*");
java// 表明只允许http://localhost:8080下的ajax访问 response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080"); // 表明允许所有的ajax访问 response.setHeader("Access-Control-Allow-Origin", "*");
- 只允许特殊路径下的ajax访问:
13.3.3 CORS说明
-
普通跨域请求
- 只需服务器端设置Access-Control-Allow-Origin
-
带cookie跨域请求
基本上不用
- 前后端都需要进行设置
- 【前端设置】根据xhr.withCredentials字段判断是否带有cookie
13.4 Nginx反向代理
非常重要,基本都是使用nginx代理完成端口和跨域处理
- 搭建一个中转 nginx 服务器,用于转发请求
- 特点
- 使用 nginx 反向代理实现跨域,是最简单的跨域方式
- 只需要修改 nginx 的配置即可解决跨域问题
- 支持所有浏览器
- 支持 session
- 不需要修改任何代码
- 不会影响服务器性能
- 使用
- 只需要配置nginx,在一个服务器上配置多个前缀来转发http/https请求到多个真实的服务器即可
- 因此该服务器上所有url都是相同的域名、协议和端口
- 对于浏览器来说,这些url都是同源的,没有跨域限制
- 而实际上,这些url实际上由物理服务器提供服务
- 服务器内的 javascript可以跨域调用所有这些服务器上的url