JavaWeb

javaWeb

HTML

标签的语法规范

<!-- 1.标签不能交叉嵌套 -->
正确:<div><span>correct</span></div>
错误:<div><span>error</div></span>
<!-- 2.标签必须正确关闭(闭合) -->
<!--   (1)有文本内容的标签(双标签) -->
正确:<div>correct</div>
错误:<div>error
<!--   (2)没有文本内容的标签(单标签) -->
正确:<br /> correct
错误:<br> or <br \> error
<!-- 3.属性必须有值,属性值必须加双引号 -->
正确:<font color="blue">correct</font>
错误1:<font color=blue>error(属性值没有加双引号)</font>
错误2:<font color>error(属性没有属性值)</font>
<!-- 4.注释不能嵌套 -->
正确:<!-- correct -->
错误:<!-- <!-- error --> -->

标签

字体-font

<!--
	font标签(字体标签),它可以用来修改文本的字体、颜色、大小(尺寸).
		color属性:修改颜色
		face属性:修改字体
		size属性:修改文本大小
-->
<font color="pink" face="宋体" size="7">字体标签(font标签)</font>

特殊字符

<!-- 
	常用的特殊字符:
		  < ==>>> &lt; (less than)
		  > ==>>> &gt: (great than)
		空格 ==>>> &nbsp;
-->
我是<br>标签
我是&lt;br&gt;标签
空     格
空&nbsp;&nbsp;&nbsp;格

标题-h1-6

<!--
  	标题标签:h1 ~ h6
		h1 -> 最大
		h6 -> 最小
	  		align属性:对齐属性
				left属性值:左对齐(默认)
				center属性值:居中
				right属性值:右对齐
-->
<h1 align="left">标题1(最大)</h1>
<h2 align="center">标题2</h2>
<h3 align="right">标题3</h3>
<h4>标题4</h4>
<h5>标题5</h5>
<h6>标题6(最小)</h6>

超链接-a

<!--
	a标签(超链接):
	   	href属性:设置链接的地址
       	target属性:设置哪个目标进行跳转
		 	 _self属性值:表示跳转到当前页面(默认值)
		 	 _blank属性值:表示打开新页面来进行跳转
-->
<a href="http://www.baidu.com">百度_默认</a><br />
<a href="http://www.baidu.com" target="_self">百度_self</a><br />
<a href="https://www.baidu.com" target="_blank">百度_blank</a><br />
<!-- 注意:http:// 不能省略,写链接地址的时候必须要加上!!! -->
<a href="www.baidu.com">完全错误(没有写http://)</a><br />

图片-img

<!--
	img标签(图片标签):用来显示图片
		src属性:设置图片的路径
		width属性:设置图片的宽度(横向,水平方向)
		height属性:设置图片的高度(纵向,竖直方向)
		border属性:设置图片边框大小
		alt属性:设置当指定路径找不到图片时,用来代替显示的文本内容

img src="" width="200" height="260" border="1" alt="图片找不到"/>
img src="" width="200" height="260"/>
-->

相对路径vs绝对路径

<!--
	在JavaSE中路径也分为 相对路径和绝对路径
		相对路径 -> 从工程名开始算 
		绝对路径 -> 盘符:/目录/文件名

	在web中路径分为 相对路径和绝对路径两种
		相对路径
			-> .	  表示当前文件所在的目录
			-> ..	  表示当前文件所在的上一级目录
			-> 文件名	表示当前文件所在目录的文件,相当于 ./文件名  
		绝对路径
			-> 正确格式是:http://ip:port/工程名/资源路径 
				(注意:http://必不可少!!)
			-> 错误格式是:盘符:/目录/文件名
-->

表格-table

<!--
	table标签(表格标签)
        table			-> 			表格标签
                border属性:设置表格边框(可以显示表格的框架结构),一般设置为1
                width属性:设置表格宽度
                height属性:设置表格高度
                align属性:设置表格相对于页面的对齐方式
                cellspacing属性:设置单元格间距,一般设置为0
            tr 			-> 			行标签
                th 		-> 		表头单元格标签(居中+加粗) 
           			等价于 <td align="center"><b>和表头标签效果相同</b></td>
                td 		-> 			单元格标签
                    align属性:设置单元格文本对齐方式
                    colspan属性:设置跨列(横向,水平方向)
                    rowspan属性:设置跨行(纵向,竖直方向)
		b -> 加粗标签
	
	犯错的地方:
		(1) 在table中只使用了tr标签,没有使用td标签,导致表格没有生效
			【强制】在table中,tr标签 和 td标签 要一起使用!!!
-->
<table border="1" width="500px" height="500px" align="center" cellspacing="0">
    <tr>
        <td align="center"><b>1.1</b></td>
        <th>1.2</th>
        <th>1.3</th>
    </tr>
    <tr>
        <td>2.1</td>
        <td>2.2</td>
        <td>2.3</td>
    </tr>
</table>

iframe标签

<!--
	iframe标签:可以在页面上开辟一个小区域显示一个单独的页面
		iframe 和 a标签(超链接)组合使用的步骤:
			-> (1) 在iframe标签中使用name属性定义一个名称
			-> (2) 在a标签的target属性上设置iframe的name的属性值
-->
<iframe src="3.标题标签.html" width="500px" height="400px" name="rnny"></iframe>
<br />

<ul>
    <li><a href="xxx.html" target="rnny">页面1</a></li>
    <li><a href="../xxx.html" target="rnny">页面2</a></li>
    <li><a href="../imgs/xxx.html" target="rnny">页面3</a></li>
</ul>

有序列表-ol

<!--
	ol标签(有序列表标签)
		ol标签 有序列表标签
			type属性:修改列表项前面的符号
		li 列表项
-->
<ol type="A">
    <li>1</li>
    <li>2</li>
</ol>

无序列表-ul

<!--
	ul标签(无序列表标签)
		ul标签 有序列表标签
			type属性:修改列表项前面的符号
				-> type="none" 表示列表项前面没有任何符号
 		li 列表项
-->
<ul>
    <li>3</li>
    <li>4</li>
</ul>

表单-form

form常用标签
<!--
	form标签(表单标签):
	给用户使用:
		input type="text"			->			文本输入框
			value:(1)可以用来设置默认显示的内容
				   (2)用户输入的数据就是value值
		input type="password"		->			密码输入框
			value:(1)可以用来设置默认显示的内容
				   (2)用户输入的数据就是value值
		input type="radio"			->			单选框
			name属性:对其进行分组
			checked="checked":表示默认选中
		input type="checkbox"		->			复选框
			checked="checked":表示默认选中
		input type="reset"			->			重置按钮
			value属性:修改按钮上的文本
		input type="submit"			->			提交按钮
			value属性:修改按钮上的文本
		input type="button"			->			普通按钮
			value属性:修改按钮上的文本
		button标签				   ->			按钮标签
			按钮上的文本:起始标签和结束标签中的内容就是按钮名称
			注意:这里不是使用value来修改按钮上的文本,与input type="button"区分.
		input type="file" 			-> 			文件上传域
		select标签				   ->		   下拉列表框
			option标签:下拉列表框中的选项
				selected="selected" 设置默认选中
		textarea标签				   ->		   多行文本输入框
				-> 起始标签和结束标签中的内容 就是默认值
			rows属性:设置可以显示几行的高度(竖直方向)
			cols属性:设置每行可以显示几个字符宽度(水平方向)
			

	给程序使用:
		input type="hidden" -> 隐藏域
			-> 当我们要发送某些信息,而这些信息,不需要用户参与,就可以使用隐藏域
			-> (提交的时候同时发送给服务器)
-->
form细节
<!--
	form标签(表单标签):
		action属性:设置提交的服务器地址
		method属性:设置提交的方式get(默认值)或post
	
	表单提交的时候,数据没有发送给服务器的三种情况:
		1、表单项没有name属性值。
		2、单选、复选、下拉列表中的option标签 都需要添加value属性及其属性值,以便发送给服务器。
		3、表单项不在提交的form标签中。
	解读:
		(1)表单项:我们使用的input,select等都属于表单项,
			即只有我们使用了form中的标签,就需要指定name值【强制】
		(2)为什么单选、复选、下拉列表中的option标签 需要强制添加value属性及其属性值,
			而输入姓名,密码的控件不是强制添加value?
		  ->答:因为姓名,密码用户可以手动输入,而单选,复选等 是用户无法手动输入的。
	技巧:其实表单给服务器的就是 name=value, 当我们写代码的时候就需要我们考虑是否有name=value.
	
	get请求的特点是:
		1、浏览器地址栏中的地址是:action属性[+?+请求参数]
			请求参数的格式是:name=value&name=value
		2、不安全
		3、它有数据长度的限制
	post请求的特点是:
		1、浏览器地址栏中只有action属性值(也就是服务器地址)
		2、相当于get请求要安全
		3、理论上没有数据长度的限制
-->

其它标签-div、span、p

<!--
	div标签 -> 默认独占一行
	span标签 -> 它的长度是封装数据的长度
	p段落标签 -> 默认会在段落的上方或下方各空出一行来(如果已有就不再空)
-->

CSS

html和css 代码注释

<!-- html注释信息 -->
/* css注释信息 */

引入CSS代码的三种方式

在标签的style属性上设置【知道就行,不要使用】

<!--
	1.在标签的style属性上设置 "key: value value;key: value;...", 修改标签样式。
-->
<div style="width: 300px; height: 100px; border: 2px solid blue;">
    软柠柠吖
</div>
<!--
	问题:这种方式的缺点?
		1.如果标签多了,样式多了,代码量非常庞大。
		2.可读性非常差。
		3.CSS代码没什么复用性可言。
-->

在head标签下的style标签中设置

<!--
	在head标签中,使用style标签 来定义各种自己需要的css样式。
		html标签 -> head标签 -> style标签
		格式如下:
            xxx {
                Key: value value;
                Key: value;
            }
		说明:
		  (1)xxx -> 选择器
		  (2)Key -> 属性(property)
		  (3): -> 冒号
		  (4)value -> 属性值
		  (5); -> 分号
		  (6)一般每行只描述一个属性。
-->

<!-- style标签 用来定义CSS样式代码 -->
<style type="text/css">
	xxx {
		Key: value value;
		Key: value;
	}
</style>

<!--
	问题:这种方式的缺点?
		1.只能在同一页面内复用代码,不能在多个页面中复用CSS代码。
		2.维护起来不方便,实际的项目中会有成千上万的页面,要到每个页面中去修改。
-->

引入外部CSS文件【强烈推荐】

html文件
<!--
	把CSS样式写成一个单独的css文件,再通过link标签引入即可复用。
		在html的head标签下的,使用link标签引入css文件,
		html标签 -> head标签 -> link标签
-->
<link rel="stylesheet" type="text/css" href="css文件路径" />
css文件
div {
    width: 123px;
    height: 567px;
    border: 2px solid blue;
    background-color: pink;
}

选择器

标签名

  • 标签名选择器
/*
	标签名选择器 
	   格式:
	      标签名 {
		      属性: 值;
		  }
	   作用:
	      标签名选择器,可以决定哪些标签被动的使用这个样式。
*/

div {
    
}
span {
    
}

id

  • id选择器
/*
	id选择器
		格式:
			#id属性值 {
				属性: 值;
			}
		作用:
			id选择器,可以让我们通过 id属性选择性的去使用某个样式。
*/

class类型

  • class类型选择器
/*
	class类型选择器
		格式:
			.class属性值 {
				属性: 值;
			}
		作用:
			class类型选择器,可以通过class属性有效的选择性地使用某个样式。
*/

组合

  • 组合选择器
/*
	组合选择器
	   格式:
		   选择器1, 选择器2, 选择器n {
		       属性: 值;
		   }
	   说明:
		(1)选择器1, 选择器2, 选择器n 可以是标签名选择器,也可以是id选择器,还可以是class类型选择器
	   作用:
	       组合选择器可以让多个选择器共用同一个css样式代码。
*/

CSS常用样式

字体

字体颜色
  • color.
/* 颜色值可以是颜色名、RGB值、十六进制值(十六进制值前必须加#). */
color: 颜色值;

color: pink; /* 颜色名 */
color: rgb(255, 192, 203); /* RGB值 */
color: #ffc0cb; /* 十六进制值(别忘了#) */
字体大小
  • font-size.

文本居中

  • text-align.
text-align: center;

宽度

  • width.

高度

  • height.

边框

  • border.
/*
	border: 边框宽度 边框线形 边框颜色;

	1像素 实线 粉色 边框
*/
border: 1px solid pink;

背景颜色

  • background-color.

div居中

margin-left: auto;
margin-right: auto;

超链接去下划线

text-decoration: none;

表格细线


列表去除修饰


JavaScript

引用js代码的两种方式

直接在html页面中书写

<!-- 
	1.在html文件中的head标签下
		使用script标签直接定义js代码 -->
<script type="text/javascript">
    JavaScript代码.....
</script>

引入外部js文件

<!-- 
	2.在html文件中的head标签下
		使用script标签引入外部的js文件来实现.
			src属性:用来引入外部js文件路径(相对路径和绝对路径都可以.)
-->
<script type="text/javascript" src="js文件"></script>

<!-- 注意:
		(1)src="js文件".格式:src="js文件名.js"
		(2)script标签可以用来定义js代码,也可以用来引入js文件
			但是,两个功能二选一使用。不能同时使用两个功能。
-->
<script type="text/javascript" src="./temp.js">
    alert("内容不能显示");// ❌❌❌,不能同时使用
</script>

<!-- 下面就可以了 不算是一起使用,是单独的使用,可以有多个script标签 -->
<script type="text/javascript" src="./temp.js"></script> <!--导入外部文件-->
<script>			
    alert("内容可以显示");// ✔️✔️✔️					  <!--直接在html页面中书写-->
</script>
/* 
	外部js文件
*/
alert("Rnny");
// JavaScript代码....

js提供的函数

alert 警告.

// 1.alert是JavaScript语言提供的一个警告框函数.
// 它可以接收任意类型的参数,这个参数就是警告框的提示信息。
alert("rnny");
// 2.typeof是JavaScript语言提供的一个函数,
// 它可以取变量的数据类型以string类型返回。
var varType = typeof 变量;

变量

变量类型

/*
	JavaScript的变量类型:
		数值类型:	number
		字符串类型:	string
		对象类型:	object
		布尔类型:	boolean
		函数类型:	function
*/

js特殊值

/*
	JavaScript里特殊的值:
		undefined:	未定义,所有js变量未赋予初始值的时候,默认值都是undefined.
		null:		空值
		NaN:		全称是:Not a Number。非数字。非数值。
*/

定义变量格式

/*		
	js中的定义变量格式:
		var 变量名;
		var 变量名 = 值;
*/
var a;
console.log(a);// undefined
a = 886;
console.log(typeof a);// number
console.log(typeof typeof a);// string
a = "rnny";
console.log(typeof a);// string
a = null;
console.log(typeof a);// object
console.log(a);// null
var b;
console.log(b);// undefined
console.log(a * b);// NaN是非数字,非数值。

关系(比较)运算

/*
	等于:		==		等于是简单的做字面值的比较(底层只会对数值类型处理)
	全等于:   ===		除了做字面值的比较之外,还会比较两个变量的数据类型
*/
var a = "123";
var b = 123;
console.log(a == b);// true 仅对数值类型有用!
console.log(a === b);// false
var c = "true";
var d = true;
console.log(c == d);// false
console.log(c === d);// false

逻辑运算

变量当做表达式使用

/*
	在JavaScript语言中,所有的变量,都可以作为一个boolean类型的变量去使用。
	0、null、undefined、""(空串) 都认为是 false
	注意:" "(包含一个空格的字符串,不是空串) 是true
*/
var a = 0;
if (a) {
    console.log("0为真");
} else {
    console.log("0为假");// ✔️
}
var b = null;
if (b) {
    console.log("null为真");
} else {
    console.log("null为假");// ✔️
}
var c = undefined;
if (c) {
    console.log("undefined为真");
} else {
    console.log("undefined为假");// ✔️
}
var d = "";
if (d) {
    console.log("空串为真");
} else {
    console.log("空串为假");// ✔️
}
var e = " ";
if (e) {
    console.log("空格串为真");// ✔️
} else {
    console.log("空格串为假");
}

&& 且运算

/*
	&& 且运算
	有两种情况:
		(1)当表达式全为真的时候,返回最后一个表达式的值。
		(2)当表达式中,有一个为假的时候,返回第一个为假的表达式的值。
*/
var a = "abc";
var b = true;
var d = false;
var c = null;
console.log(a && b);// true
console.log(b && a);// "abc"
console.log(a && d);// false
console.log(c && d);// null

|| 或运算

/*
	|| 或运算
	也有两种情况:
		(1)当表达式全为假时,返回最后一个表达式的值。
		(2)只要有一个表达式为真,就会返回第一个为真的表达式的值。
*/
// abcd看上面
console.log(a || b);// "abc"
console.log(b || a);// true
console.log(a || d);// "abc"
console.log(c || d);// false

数组

数组定义方式

/*
	js中 数组的定义
	   格式:
	      var 数组名 = []; // 空数组
		  var 数组名 = [1, "abc", true]; // 定义数组,同时赋值元素(元素类型随意,都可以)
			
	   注意:赋值可能会扩容,访问一定不会扩容。
		  (1)JavaScript语言中的数组,只要我们通过数组下标赋值,
				那么最大的下标值(当大于等于数组的原长度时),底层会使数组自动的做扩容操作.
		  (2)访问时,不会进行扩容操作。
		  	 (i)访问数组下标为[0 ~ length-1] 的元素:
		  	 		如果赋值则显示赋值之后的元素(任意类型, 可以被覆盖),
		  	 		没有赋值则显示undefined.
		  	 (ii)访问数组下标为[length ~ +♾️) 的元素:
		  	 		因为没有赋值,所以显示undefined.
		  	 		(也不可能赋值,一旦赋值就会使数组自动扩容)
*/
var arr = []; // 空数组
console.log(arr.length);// 0
console.log(arr[0]);// undefined, 访问不会造成扩容
arr[6] = 66;// 赋值造成数组自动扩容
console.log(arr.length);// 7 (arr.length - 1 = 6 --> arr.length = 7)
console.log(arr[5]);// undefined
console.log(arr[6]);// 66
// 遍历数组
for (var i = 0; i < arr.length; i++) {// 这里不能使用int, 而是需要使用var
    console.log(arr[i]);
}

函数

函数的两种定义方式

/*
	第一种,使用function关键字来定义函数
		格式:
			function 函数名(形参列表) {
				函数体;
			}
		说明:
			在JavaScript语言中,如何定义带有返回值的函数?
			答:只需要在函数体内 直接使用return语句 返回值即可!
*/

// 1、定义一个无参函数
function fun1() {
    alert("无参函数fun1()被调用了!");
}
// 函数调用才会执行
fun1();

// 2、定义一个有参函数
function fun2(a, b) {
    alert("有参函数fun2()被调用了 a=>" + a + ",b=>" + b);
}
fun2(120, "rnny");// 调用有参函数
// 3、定义带有返回值的函数
function sum(num1, num2) {
    var result = num1 + num2;
    return result;
}
alert(sum(100, 66));// 调用有返回值的函数

/*
	注意:
		(1)只定义函数,函数是不会起作用的,需要我们调用函数才能使函数起作用。
		(2)有参函数的形参列表 只需要变量名,不需要数据类型var等.
		(3)返回值函数加上return即可,不需要返回值的数据类型(与Java区分).
*/
/*
	第二种,使用var 和 function来定义函数
		格式:
			var 函数名 = function (形参列表) {
				函数体;
			}
*/
// 定义一个无参函数
var fun1 = function () {
    alert("无参函数fun1()被调用了.");
};
// 函数调用才会执行
fun1();
// 定义一个有参函数
var fun2 = function (a, b) {
    alert("有参函数fun2()被调了.. a=>" + a + ",b=>" + b);
};
fun2("Rnny", 18);
// 定义带有返回值的函数
var fun3 = function (num1, num2) {
    var result = num1 + num2;
    return result;
}
alert(fun3(66, 11));

js中函数不能重载

// 注:在Java中函数允许重载。
// 	但是在js中函数的重载会直接覆盖掉上一次的定义。
function fun(a, b) {
    alert("有参函数fun(a, b)被调用了...")
}
function fun() {
    alert("无参函数fun()被调用了...");
}
fun(12, 32);// 无参函数fun()被调用了...

arguments隐形参数

/*
	函数的arguments 隐形参数(只在function函数内)
		说明:
			(1)隐形参数:就是在function函数中不需要定义,但却可以直接用来获取所有参数的变量。
			(2)隐形参数特别像Java基础的可变长参数一样,
				public void fun(Object... args){};
				可变长参数其实就是一个数组。
			(3)js中的隐形参数也跟Java的可变长参数一样,操作类似数组。
*/
// 无参函数
function fun() {
    alert(arguments.length);// 参数个数
    alert(typeof arguments);// Object
    alert(typeof arguments[0]);// 参数的类型(看实际情况)
    alert(arguments[0]);
    for (var i = 0; i < arguments.length; i++) {
        alert(arguments[i]);
    }

    alert("无参函数fun()被调用了...");
}
fun("12");

// 有参函数
function fun(a, b) {
    alert("arguments[0]=" + arguments[0]);// 12
    alert("arguments[1]=" + arguments[1]);// undefined
    alert("a=" + a);// 12
    alert("b=" + b);// undefined
    for (var i = 0; i < arguments.length; i++) {
        alert(arguments[i]);
    }
    alert("有参函数fun(a, b)被调用了...");
}
fun("12");

// 需求:要求 编写一个函数。用于计算所有参数相加的和 并返回(提示:参数个数未知).
function sum(num1, num2) {
    var result = 0;
    for (let i = 0; i < arguments.length; i++) {
        if (typeof arguments[i] == "number") {
            result += arguments[i];
        }
    }
    return result;
}
alert(sum(1, 2, 3, 4, "5"));// 10
/*
	说明:
		(1)这里形参列表写几个变量都不是很合适,但是还是写了两个变量,
			实际上并没有使用这两个变量,仅仅是为了好看,中看不中用,使用的是隐形参数arguments。
		(2)JavaScript中 字符串的比较使用 == 或 ===.
*/

js中的自定义对象

Object形式的自定义对象

/*
	Object形式的对象
	定义:
		var 变量名 = new Object();   // 对象实例(空对象)
		变量名.属性名 = 值;		   // 定义一个属性
		变量名.函数名 = function () {} // 定义一个函数
		
	对象的访问
		访问属性:
			变量名.属性;
		访问函数:
			变量名.函数名();
*/

// 定义对象
var obj = new Object();
obj.name = "rnny";
obj.age = 18;
obj.info = function () {
    alert(this.name + " " + this.age);
}
// 访问对象
alert(obj);
alert(obj.name);
obj.info();

{}花括号形式的自定义对象

/*
	{}花括号形式的对象
	定义:
		var 变量名 = {			   // 空对象
			属性名: 值,			  // 定义一个属性
			属性名: 值,			  // 定义一个属性
			函数名: function () {}, // 定义一个函数
			函数名: function () {} // 定义另一个函数
		};
	对象的访问
		访问属性
			变量名.属性;
		访问方法
			变量名.函数名();
*/

// 定义对象
var obj = {
    name: "Rnny",
    age: 18,
    info: function () {
        alert(this.name + " " + this.age);
    },
    eat: function () {
        alert(this.name + " 吃雪糕");
    }
};
// 访问对象
obj.info();
obj.eat();

js中的事件

事件的注册

  • 什么是事件的注册(绑定)?
  • 其实就是告诉浏览器,当事件响应后要执行哪些操作代码,叫事件注册或事件绑定。
静态注册
  • 通过html标签的事件属性直接赋予事件响应后的代码,这种方式叫静态注册。
动态注册
  • 是指先通过js代码得到标签的dom对象,然后再通过 dom对象.事件名 = function() {} 这种形式赋予响应后的代码,叫动态注册。
/*
	动态注册基本步骤:
		1、获取标签对象
		2、标签对象.事件名 = function () {}
*/

常用的事件

onload 加载完成事件
/*
	onload 加载完成事件
		(1)onload事件 是浏览器解析完页面之后就会自动触发的事件。
		(2)常用于做页面js代码初始化操作。
	
*/
// 事件的静态注册
// 1、<body onload="onloadStaticFun();">
// 2、
function onloadStaticFun() {
    alert("静态Static注册onload事件");
    // JavaScript代码...
}

// 事件的动态注册, 固定写法
window.onload = function () {
    alert("动态Dynamic注册onload事件")
}
onclick 单击事件
/*
	onclick单击事件
		常用于按钮的点击响应操作。
*/

// 事件的静态注册
//  1、<button onclick="onclickFun();">静态注册</button>
//  2、
function onclickFun() {
    alert("静态注册onclick事件");
}
// 事件的动态注册, 固定写法
//  1、<button id="btn">动态注册</button>
//  2、
window.onload = function () {
    // 1.获取标签对象
    /*
    * document 是JavaScript语言提供的一个对象(文档)
    * get      获取
    * Element   元素(就是标签)
    * By        通过...
    * Id        id属性
    *
    * getElementById    通过id属性获取标签对象
    **/
    var btnObj = document.getElementById("btn");
    // alert(btnObj);// [object HTMLButtonElement]
    // 2.标签对象.事件名 = function () {}
    btnObj.onclick = function () {
        alert("动态注册onclick事件");
    }
}
onblur 失去焦点事件
/*
	onblur失去焦点事件
		常用于输入框失去焦点后验证其输入内容是否合法。
*/
// 失去焦点事件的静态注册
// 1、账号:<input type="text" onblur="onblurFun();">
// 2、
function onblurFun() {
    // console 是控制台对象,是由JavaScript语言提供,
    //  专门用来向浏览器的控制器打印输出,用于测试使用.
    // log() 是打印的方法.
    console.log("静态注册失去焦点事件..");
}

// onblur事件的动态注册, 固定写法
// 1、密码:<input type="password" id="pwd">
// 2、
window.onload = function () {
    // 1.获取标签对象
    var pwdObj = document.getElementById("pwd");
    // alert(pwdObj);// [object HTMLInputElement]
    // 2.通过标签对象.事件名 = function () {}
    pwdObj.onblur = function () {
        console.log("动态注册失去焦点事件..");
    }
}
onchange 内容发生改变事件
/*
	onchange内容发生改变事件
		常用于下拉列表和输入框内容发生改变后操作。
*/

// 内容改变事件的静态注册
// 1、<select name="" onchange="onchangeFun();"><option>乒乓球</option></select>
// 2、
function onchangeFun() {
    console.log("静态注册内容改变事件..");
}

// onchange事件的动态注册, 固定写法
// 1、<select name="省份" id="city"><option value="广州">广州</option></select>
// 2、
window.onload = function () {
    // 1.获取标签对象
    var cityObj = document.getElementById("city");
    // alert(cityObj);// [object HTMLSelectElement]
    // 2.通过标签对象.事件名 = function () {}
    cityObj.onchange = function () {
        // console.log(cityObj.name);// 省份
        // console.log(cityObj.value);// 广州
        console.log("动态注册onchange事件..");
    }
}
onsubmit 表单提交事件
/*
	onsubmit表单提交事件
		常用于表单提交前,验证所有表单项是否合法。
*/
// 表单提交事件的静态注册
// 1、<form action="http://localhost:8080" method="get" onsubmit="return onsubmitFun();">
//        <input type="submit" value="静态注册">
//    </form>
// 2、
function onsubmitFun() {
    // 要验证所有表单项是否合法,如果有一个不合法就阻止表单提交。
    console.log("静态注册表单提交事件..发现不合法!");
    return false;// 可以阻止表单提交
}
/*
	静态注册说明:
		(1)onsubmit是form的一个事件,而不是input的事件.
			因为我们要提交一个表单给服务器,而不是仅仅提交一个按钮(表单项)给服务器.
		(2)onsubmit事件如果返回false,则会阻止表单的提交.
		(3)这里我们需要 onsubmit="return onsubmitFun();" 其中的return是不能少的.
			因此我们需要写至少两个return,表面上一个return以及onsubmitFun()里面的return.
*/

// onsubmit事件的动态注册, 固定写法
// 1、<form action="http://localhost:8080" method="get" id="form01">
//        <input type="submit" value="动态注册">
//    </form>
// 2、
window.onload = function () {
    // 1.获取标签对象
    var formObj = document.getElementById("form01");
    // alert(formObj);// [object HTMLFormElement]
    // 2.通过标签对象.事件名 = function () {}
    formObj.onsubmit = function () {
        // 要验证所有表单项是否合法,如果有一个不合法就阻止表单提交。
        console.log("动态注册onsubmit事件..发现不合法!");
        return false;// 可以阻止表单提交
    }
}
/*
	动态注册说明:
		(1)获取标签对象【document.getElementById("form01")】,这里我们需要根据id来获取form表单对象,而不是获取input标签对象.
			因为我们需要提交表单给服务器,而不是一个提交按钮(表单项)给服务器.
		(2)onsubmit事件如果返回false,则会阻止表单的提交.
		(3)这里的return语句只有onsubmit事件中的return语句,比静态注册简单一点,少一个return语句
*/

DOM模型

  • DOM 全称是 Document Object Model 文档对象模型.
  • 大白话,就是把文档中的标签属性文本 转换成对象来管理。

Document对象

image-20220409143254136.

Document 对象的理解
  • 第一点:Document它管理了所有的HTML文档内容.
  • 第二点:document 它是一种树结构的文档。有层级关系。
  • 第三点:它让我们把所有的标签 都 对象化。
  • 第四点:我们可以通过 document 访问所有的标签对象。
对象化
  • html标签的对象化:
<body>
	<div id="div01">div01</div>
</body>
<!-- 模拟对象化,相当于
class Dom {
	private String id;// id属性
	private String tagName;// 标签名
	private Dom parentNode;// 父亲对象
	private List<Dom> children;// 孩子节点集
	private String innerHTML;// 起始节点和结束节点中间的内容

}
-->

Document对象中的方法介绍

document.getElementById(elementId)
  • 通过标签的id属性查找(获取)标签dom对象,elementId是标签的id属性值.
/*	body代码块中的代码
   账号:<input type="text" id="userName">
   <span id="userNameSpan" style="color: red"></span>
   <br>
   <input type="button" value="校验" onclick="onclickFun();">
 * */

/*
	需求:当用户点击了校验按钮,获取输出框中的内容,然后验证其是否合法。
    验证的规则是:必须由字母,数字。下划线组成。并且长度是 5 到 12 位。
*/
function onclickFun() {
    // 1.当我们要操作一个标签的时候,一定要先获取这个标签对象。
    var userNameObj = document.getElementById("userName");
    // alert(userNameObj);// [object HTMLInputElement] 这就是dom对象
    // 2.获取dom对象的value
    var userValue = userNameObj.value;
    // 3.使用正则表达式技术,验证字符串是否符合规则.
    /*
	 *	正则表达式说明:
	 *		1.正则表达式使用/表示开始和结束,即 /正则表达式内容/ 的形式.
	 *			而不是字符串的形式("字符串内容"),注意区分!
     *      2.注意{5,12}中的,与12之间没有空格!没有空格!!
     * */
    var pattern = /^\w{5,12}$/;
    /*
     *   test()方法用于测试某个字符串 是不是匹配我的规则,
     *       匹配就返回true,不匹配就返回false.
     * */
    var legal = pattern.test(userValue);
    var spanObj = document.getElementById("userNameSpan");
    /*
     *   innerHTML 表示起始标签和结束标签中的内容.
     *   innerHTML 这个属性可读,可写.
     * */
    spanObj.innerHTML = "Rnny!";
    if (legal) {
        // alert("用户合法!");
        // alert(spanObj.style);// [object CSSStyleDeclaration]
        spanObj.style.color = "green";
        //alert(typeof spanObj.style.color)
        //spanObj.innerHTML = "用户合法!";
        spanObj.innerHTML = "<img src=\"./right.png\" width=\"18px\" height=\"18px\">";
    } else {
        // alert("用户不合法!");
        //spanObj.innerHTML = "用户不合法!";
        spanObj.innerHTML = "<img src=\"./wrong.png\" width=\"18px\" height=\"18px\">";
    }
}
document.getElementsByName(elementName)
  • 通过标签的name属性查找(获取)标签dom对象列表,elementName是标签的name属性.
/* body中的代码
 	兴趣爱好:
 	<input type="checkbox" name="hobby" value="cpp">c++
    <input type="checkbox" name="hobby" value="java">java
    <input type="checkbox" name="hobby" value="python">python
    <br>
    <input type="button" value="全选" onclick="checkAll();">&nbsp;&nbsp;&nbsp;
    <input type="button" value="全不选" onclick="checkNo();">&nbsp;&nbsp;&nbsp;
    <input type="button" value="反选" onclick="checkReverse();">
 * */
// 全选
function checkAll() {
    // 让所有复选框都选中
    // document.getElementsByName(); 是根据 指定的name属性查询返回多个标签对象集合.
    // 这个集合的操作跟数组 一样
    // 集合中每个元素都是 dom对象
    // 这个集合中的元素顺序是它们在html页面中从上到下的顺序
    var hobbies = document.getElementsByName("hobby");
    // alert(hobbyObjs);// [object NodeList]
    for (let i = 0; i < hobbies.length; i++) {
        // checked 表示复选框的选中状态。选中是true,不选中是false.
        // checked 这个属性可读,可写.
        hobbies[i].checked = true;
    }
}

// 全不选
function checkNo() {
    var hobbies = document.getElementsByName("hobby");
    // alert(hobbyObjs);// [object NodeList]
    for (let i = 0; i < hobbies.length; i++) {
        // checked 表示复选框的选中状态。选中是true,不选中是false.
        // checked 这个属性可读,可写.
        hobbies[i].checked = false;
    }
}

// 反选
function checkReverse() {
    var hobbyObjs = document.getElementsByName("hobby");
    // alert(hobbyObjs);// [object NodeList]
    for (let i = 0; i < hobbyObjs.length; i++) {
        // if...else...
        // if (hobbyObjs[i].checked) {
        //     hobbyObjs[i].checked = false;
        // } else {
        //     hobbyObjs[i].checked = true;
        // }

        // 三目运算符
        // hobbyObjs[i].checked = hobbyObjs[i].checked ? false : true;

        // 最简表达式
        hobbyObjs[i].checked = !hobbyObjs[i].checked;
    }
}
document.getElementsByTagName(tagName)
  • 通过标签名查找(获取)标签dom对象列表,tagName是标签名.
/* body中的代码...
	兴趣爱好:
    <input type="checkbox" name="hobby" value="cpp">c++
    <input type="checkbox" name="hobby" value="java">java
    <input type="checkbox" name="hobby" value="python">python
    <br>
    <button onclick="checkAll();">全选</button>
* */

// 全选
function checkAll() {
    // document.getElementsByTagName("input");
    // 是按照指定标签名来进行查询并返回集合
    // 这个集合的操作跟数组 一样
    // 集合中都是 dom对象
    // 集合中元素顺序 是它们在html页面中从上到下的顺序.
    var inputs = document.getElementsByTagName("input");
    // alert(hobbies);// [object HTMLCollection]
    for (let i = 0; i < inputs.length; i++) {
        inputs[i].checked = true;
    }
}
总结
  • 方法的选择标准
/*
	document对象的三个查询方法选择标准
		如果有id属性,优先使用getElementById方法来进行查询;
		如果没有id属性,但有name属性,则优先使用getElementsByName方法来查询;
		如果id属性和name属性都没有,最后才按标签名getElementsByTagName方法来查询.
*/

  • 执行时期
/* 
	以上三个方法,一定要在页面加载完成之后执行,才能查询到标签对象。
	说明:
		页面加载完成之后 => window.onload = function () {}
					 =或=> function onclick() {}
*/

document.createElement(tagName)
  • 通过给定的标签名,创建一个标签对象。tagName是要创建的标签名.
window.onload = function () {
    // 使用js代码来创建html标签,并显示在页面上
    // 标签的内容是:<div>Rnny</div>
    var divObj = document.createElement("div");// 在内存中 <div></div>
    var textNodeObj = document.createTextNode("Rnny");// 有一个文本节点对象 Rnny
    divObj.appendChild(textNodeObj);// <div>Rnny</div>
    // divObj.innerHTML = "ok";// <div>ok<div>, 但 还只是在内存中
    // 添加子元素
    document.body.appendChild(divObj);
}

节点常用属性

  • 节点就是标签对象
childNodes
  • 属性,获取当前节点的所有子节点。
firstChild
  • 属性,获取当前节点的第一个子节点。
lastChild
  • 属性,获取当前节点的最后一个子节点。
parentNode
  • 属性,获取当前节点的父节点。
nextSibling
  • 属性,获取当前节点的下一个节点。
previousSibling
  • 属性,获取当前节点的上一个节点。
className
  • 用于获取或设置标签的class属性值。
innerHTML
  • 属性,表示获取/设置起始标签和结束标签中的内容。
innerText
  • 属性,表示获取/设置起始标签和结束标签中的文本。

节点常用方法

  • 通过具体的元素节点调用。
getElementsByTagName()
  • 方法,获取当前节点的指定标签名孩子节点。
appendChild(oChildNode)
  • 方法,可以添加一个子节点,oChildNode是要添加的孩子节点。

jQuery

常见问题?

  1. 使用jQuery一定要引入jQuery库吗? 答:是的,必须。
  2. jQuery中的$到底是什么? 答:它是一个函数。
  3. 怎么为按钮添加点击响应函数? 答:
    1. 使用jQuery查询到标签对象。
    2. 使用标签对象.click(function () {});

jQuery核心函数

  • $是jQuery的核心函数,能完成jQuery的很多功能。$()就是调用$这个函数。
    1. 传入参数为【 函数 】时:
      • 表示页面加载完成之后。相当于window.onload = function () {}
    2. 传入参数为【 HTML 字符串 】时:
      • 在内存中创建这个html标签对象。
    3. 传入参数为【 选择器字符串 】时:
      • $("#id属性值"); id选择器,根据id查询标签对象。
      • $("标签名"); 标签名选择器,根据指定的标签名查询标签对象。
      • $(".class属性值"); 类型选择器,根据class属性查询标签对象。
    4. 传入参数为【 DOM对象 】时:
      • 把这个DOM对象转换为jQuery对象。

jQuery对象和DOM对象区分

DOM对象

  1. 通过 getElementById() 查询出来的标签对象是DOM对象。
  2. 通过 getElementsByName()查询出来的标签对象是DOM对象。
  3. 通过 getElementsByTagName()查询出来的标签对象是DOM对象。
  4. 通过 createElement() 方法创建的对象,是DOM对象。
    • DOM对象 alert() 出来的效果是:[object HTML标签名Element]

jQuery对象

  1. 通过jQuery提供的API创建的对象,是jQuery对象。
  2. 通过jQuery包装的DOM对象,是jQuery对象。
  3. 通过jQuery提供的API查询到的对象,是jQuery对象。
    • jQuery对象 alert() 出来的效果是:[object Object]

注意:通过jQuery查询到的对象数组中的具体的每个对象,依旧是DOM对象,而不是jQuery对象。这点需要注意!!

jQuery对象的本质

  • jQuery对象 = DOM对象的数组 + jQuery提供的一系列功能函数。

jQuery对象 和 DOM对象使用区别

  • jQuery对象不能使用DOM对象的属性和方法。
  • DOM对象也不能使用jQuery对象的属性和方法。

DOM对象和jQuery对象互相转化

  • DOM对象转化为jQuery对象
    1. 先有DOM对象
    2. $( DOM对象 ); 就可以转化成 jQuery对象
  • jQuery对象转化为DOM对象
    1. 先有jQuery对象
    2. jQuery对象[下标]; 取出相应的DOM对象。

示意图

image-20220413144121035.

jQuery选择器

基本选择器

/* 基本选择器
#ID		选择器:根据id查找标签对象
.class	选择器:根据class查找标签对象
element	选择器:根据标签名查找标签对象
*		选择器:表示任意的,所有的元素
selector1, selector2 组合选择器:合并选择器1, 选择器2的结果并返回。
	注意:(1)这里使用的是"," 而不是空格.
		 (2)合并的是各个选择器的结果,而不是合并筛选条件.
		 
p.myClass:表示标签名必须是p标签,而且class类型还要是myClass.
*/

层级选择器

/*
ancestor descendant	后代选择器:在给定的祖先元素下匹配所有的后代元素
	注意:(1)不限于直接子代, 儿子、孙子...都可以
		 (2)所有的后代元素,不只是一个.
		 (3)这里就是使用的空格了,而不是使用"," 
		 (4)","逗号一般是表示并列情况。
parent > child		子元素选择器:在给定的父元素下匹配所有的子元素
	注意:(1)这里仅限于直接子代,即只能是儿子
		 (2)所有的直接子代元素,不只是一个.
prev + next			相邻元素选择器:匹配所有紧挨在prev 元素后的 next 元素
	注意:(1)这里匹配的是所有prev 元素相邻的下一个next元素
prev ~ siblings		之后的兄弟元素选择器:匹配 prev 元素之后的所有 siblings 元素。
	注意:(1)这里匹配的是prev 元素的所有兄弟siblings 元素。


*/

过滤选择器

基本过滤器
/*
:first			获取第一个元素
:last			获取最后一个元素
:not(selector)	去除所有与给定选择器匹配的元素
:even			匹配所有索引值为偶数的元素,从0开始计数
:odd			匹配所有索引值为奇数的元素,从0开始奇数
:eq(index)		匹配一个给定索引值的元素
:gt(index)		匹配所有大于给定索引值的元素(greater than)
:lt(index)		匹配所有小于给定索引值的元素(less than)
:header			匹配如 h1, h2, h3之类的标签元素
:animated		匹配所有正在执行动画效果的元素
*/
内容过滤器
/*
:contains(text)	匹配包含给定文本的元素
:empty			匹配所有不包含子元素或文本的空元素
:parent			匹配含有子元素或文本的非空元素
:has(selector)	匹配含有选择器所匹配的元素的 元素
*/
属性过滤器
/*
[attribute]						匹配包含给定属性的元素
[attribute=value]				匹配给定的属性是某个特定值的元素
[attribute!=value]				匹配所有不含有指定的属性,或者属性不等于特定值的元素
[attribute^=value]				匹配给定的属性是以某些值开始的元素
[attribute$=value]				匹配给定的属性是以某些值结尾的元素
[attribute*=value]				匹配给定的属性是以包含某些值的元素
[attrSel1][attrSel2][attrSelN]	复合属性选择器,需要同时满足多个条件时使用
*/
表单过滤器
/*
:input		匹配所有 input、textarea、select 和 button元素
:text		匹配所有文本输入框 input type="text"
:password	匹配所有的密码输入框 input type="password"
:radio		匹配所有的单选框 input type="radio"
:checkbox	匹配所有的复选框 input type="checkbox"
:submit		匹配所有提交按钮 input type="submit"
:image		匹配所有img标签 
:reset		匹配所有重置按钮 input type="reset"
:button		匹配所有普通按钮 input type="button" 或 <button>
:file		匹配所有文件上传 input type="file"
:hidden		匹配所有不可见元素 input type="hidden" 或 display:none
*/
表单对象属性过滤器
/*
:enabled	匹配所有可用元素
:disabled	匹配所有不可用元素
:checked	匹配所有选中的单选,复选(不包括下拉列表select中选中的option标签元素)
:selected	匹配所有选中的option
*/

jQuery元素筛选

/* 方法
eq()			获取给定索引的元素						功能跟 :eq() 一样
first()			获取第一个元素							 功能跟 :first 一样
last()			获取最后一个元素						功能跟 :last 一样
filter(exp)		留下匹配的元素
is(exp)			判断是否匹配给定的选择器,只要有一个匹配就返回true
has(exp)		返回包含有匹配选择器的元素的元素		  功能跟 :has 一样
not(exp)		删除匹配选择器的元素					  功能跟 :not 一样
children(exp)	返回匹配给定选择器的子元素				功能跟 parent>child 一样
find(exp)		返回匹配给定选择器的后代元素			    功能跟 ancestor descendant 一样

next()			返回当前元素的下一个兄弟元素			    功能跟 prev+next 一样
nextAll()		返回当前元素后面所有的兄弟元素			   功能跟 prev~siblings 一样
nextUntil()		返回当前元素到指定匹配的元素为止的后面元素
parent()		返回父元素
prev()			返回当前元素的上一个兄弟元素
prevAll()		返回当前元素前面所有的兄弟元素
prevUntil(exp)	返回当前元素到指定匹配的元素为止的前面元素
siblings(exp)	返回所有兄弟元素
add()			把add匹配的选择器的元素添加到当前jQuery对象中
*/

jQuery的属性操作

jQuery属性操作

/*
html()		它可以设置和获取起始标签和结束标签中的内容	跟dom属性innerHTML一样.
				a.html()	取出a的html值
				a.html(val)	让a的html值变为val
text()		它可以设置和获取起始标签和结束标签中的文本	跟dom属性innerText一样.
				b.text()	取出b的text值
				b.text(val)	让b的文本值变为val
val()		(1)它可以设置和获取 表单项 的value属性值 		跟dom属性value一样.
			(2)val()方法可以同时设置多个表单项的选中状态.
				c.val()  	取出a的val值(表单项)
				c.val(v)	设置a的value值为v
	注意:表单项是指 input type="xxx" 或<button> 这样的形式.
	
attr()		可以设置和获取属性的值,不推荐操作checked、readOnly、selected、disabled等等
			attr()方法还可以操作非标准的属性。比如自定义属性:abc, bbj
			
prop()		可以设置和获取属性的值,只推荐操作checked、readOnly、selected、disabled等等
*/

全选,全不选,反选


DOM的增删改

内部插入

/*	内部插入 -> 成为子元素
appendTo()		a.appendTo(b)	把a插入到b的子元素末尾,成为最后一个子元素
								子节点.appendTo(父节点)
prependTo()		a.prependTo(b)	把a插到b所有子元素前面,成为第一个子元素
*/

外部插入

/* 外部插入 -> 成为兄弟元素
insertAfter()		a.insertAfter(b)		得到ba
insertBefore()		a.insertBefore(b)		得到ab
*/

删除

/*
remove()		a.remove();		删除a标签(结构+内容都删除)
empty()			a.empty();		清空a标签里的内容(保留结构)
*/

替换

/*
replaceWith()	a.replaceWith(b)	把b替换掉a
replaceAll()	a.replaceAll(b)		用a替换掉所有b
*/

从左到右,从右到左练习

动态添加、删除表格记录

CSS样式操作

/*
css()			读写匹配元素的样式属性
					a.css('color')			取出a元素的color值
					a.css('color', "red")	设置a元素的color为red
addClass()		添加样式, 为元素添加一个class值 eg.<div class="mini big"></div>
removeClass()	删除样式, 删除元素的class值. 如果传递一个具体的class值,就会删除具体的某个class
					b.removeClass()			移除所有的class值
toggleClass()	有就删除,没有就添加样式。
offset()		获取和设置元素的坐标
	注意:
		(1)通过offset获取到的是一个对象,这个对象有两个属性 top(顶边距) 和 left(左边距)
		(2)调用offset设置元素位置时,也需要传递一个js对象,对象有两个属性top和left
			eg. offset({top: 10, left: 30});
				没有px, 但是要有{}
*/

jQuery动画

/*
	基本动画
		show()		将隐藏的元素显示
		hide()		将可见的元素隐藏
		toggle()	可见就隐藏,不可见就显示
			以上动画方法都可以添加参数:
				1、第一个参数是动画 执行的时长,以毫秒为单位.
				2、第二个是动画的回调函数(动画完成后自动调用的函数)
			注意:
				var fun = function () {}
				1、fun	表示这个函数 -> 本质就是一个函数function
				2、fun()	表示调用这个函数 -> 本质是函数的调用, 不是一个函数
		
	淡入淡出动画
		fadeIn()		淡入(慢慢可见)
		fadeOut()		淡出(慢慢消失)
		fadeTo()		在指定时长内慢慢的将透明度修改到指定的值。0透明,1完全可见,0.5半透明
		fadeToggle()	淡入/淡出 切换
*/

jQuery事件操作

$( function () {} ); 和 window.onload = function () {} 的区别

触发时间
  1. jQuery 的页面加载完成之后是浏览器的内核解析完页面的标签 创建好DOM对象之后就会马上执行.
  2. 原生js的页面加载完成之后,除了要等浏览器内核解析完标签 创建好DOM对象,还要等标签显示时需要的内容加载完成.
触发顺序
  1. jQuery页面加载完成之后 先执行.
  2. 原生js的页面加载完成之后
执行次数
  1. 原生js的页面加载完成之后,只会执行最后一次的赋值函数.
  2. jQuery的页面加载完成之后是全部把注册的function函数,依次顺序全部执行

jQuery中其它的事件处理方法

/*
click()			它可以绑定单击事件,以及触发单击事件
mouseover()		鼠标移入事件
mouseout()		鼠标移出事件
bind()			可以给元素一次性绑定一个或多个事件
	bind(type, [data], fn)函数 把元素和事件绑定起来
		type	要绑定的事件字符串
		[data]	传入的数据
		fn		事件的处理方法
	注意:
		1、bind(事件字符串, 回调函数),后来添加的元素不会绑定事件.
		2、使用bind()绑定多个事件,type可以接受多个事件类型,使用 空格 分隔多个事件
	eg. $(".head").bind("click mouseover", function () {
			$(".content").toggle();
		})
one()			使用上跟bind一样。但是one方法绑定的事件只会响应一次

unbind()		跟bind方法是相反的操作,解除事件的绑定
live()			也是用来绑定事件。它可以用来绑定选择器匹配的所有元素的事件。
					哪怕这个元素是后面动态创建出来的也有效
*/

事件的冒泡

  • 什么是事件的冒泡?
    • 事件的冒泡是指 父子元素同时监听同一个事件,当触发子元素的事件的时候,同一个事件也被传递到了父元素的事件里去响应。
  • 如何阻止事件冒泡?
    • 在子元素事件函数体内,return false; 可以阻止事件的冒泡传递.

JavaScript事件对象

  • 事件对象,是封装有触发的事件信息的一个JavaScript对象。
  • 如何获取JavaScript事件对象呢?
    • 在给元素绑定事件的时候,在事件的 function(event) 参数列表中添加一个参数,这个参数名,我们习惯取名为event.
    • 这个event就是JavaScript传递参数处理函数的事件对象。

XML

Tomcat

JavaWeb基本介绍

JavaWeb

  • JavaWeb是指 所有通过Java语言编写可以通过浏览器访问的程序的总称,叫JavaWeb.
  • JavaWeb是基于请求和响应来开发的.

请求

  • 请求是指 客户端给服务器发送数据,叫请求Request.

响应

  • 响应是指 服务器给客户端回传数据,叫响应Response.

请求和响应的关系

  • 请求和响应是成对出现的,有请求就有响应。
  • 示意图

image-20220502150501814.

Web资源的分类

  • Web资源按实现的技术和呈现的效果的不同,又分为静态资源和动态资源两种。
    • 静态资源:html、css、js、txt、mp4视频、jpg图片.
    • 动态资源:jsp页面、Servlet程序.

Tomcat的使用

安装

  • 找到你需要用的Tomcat版本对应的zip压缩包,解压到需要安装的目录即可。

Tomcat目录结构

bin -> 专门用来存放Tomcat服务器的可执行程序.
conf -> 专门用来存放Tomcat服务器的配置文件.
lib -> 专门用来存放Tomcat服务器的jar包.
logs -> 专门用来存放Tomcat服务器运行时输出的日志信息.
temp -> 专门用来存放Tomcat运行时产生的临时数据.
webapps -> 专门用来存放部署的Web工程.
work -> 是Tomcat工作时的目录,用来存放Tomcat运行时jsp翻译为Servlet的源码和Session钝化(序列化)的目录.

IDEA中整个动态web工程目录结构示意图

image-20220503092344205.

Servlet

Servlet技术

Servlet基本介绍

  1. ServletJavaEE 规范之一。规范就是接口
  2. Servlet是JavaWeb三大组件之一。三大组件分别是:Servlet程序、Filter过滤器、Listener监听器。
  3. Servlet是运行在服务器上的一个java小程序,它可以接收客户端发送过来的请求,并响应数据给客户端

Servlet类的继承体系

  • IDEA简单体系图

image-20220504095202893.

  • 完整体系图

image-20220504095744094.

1、手动实现Servlet程序

  1. 编写一个类去实现Servlet接口.
  2. 实现service方法处理请求,并响应数据.
  3. web.xml中去配置servlet程序的访问地址.
Servlet程序
public class MyServlet implements Servlet {
    /**
     * service 方法是专门用来处理请求和响应的
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("MyServlet 被访问了...");
    }
}
web.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- servlet标签 -> 			给Tomcat配置Servlet程序 -->
    <servlet>
        <!-- servlet-name标签 -> 		给Servlet程序起一个别名(一般是类名) -->
        <servlet-name>MyServlet</servlet-name>
        <!-- servlet-class标签 -> 	是Servlet程序的全类名 -->
        <servlet-class>com.rnny.servlet.MyServlet</servlet-class>
    </servlet>
    <!-- servlet-mapping标签 -> 	给servlet程序配置访问地址 -->
    <servlet-mapping>
        <!-- servlet-name标签 -> 		告诉服务器, 当前配置的地址给哪个Servlet程序使用 -->
        <servlet-name>MyServlet</servlet-name>
        <!-- url-pattern 标签 -> 		配置访问地址 <br />
                / 斜杠在服务器解析的时候,表示地址为:http://服务器ip:port/工程路径   <br />
                /my 表示地址为:http://服务器ip:port/工程路径/my                  <br />
         -->
        <url-pattern>/my</url-pattern>
    </servlet-mapping>
</web-app>

url地址到Servlet程序的访问示意图

image-20220503104716120.

Servlet的生命周期

  1. 执行Servlet构造器方法.
  2. 执行init初始化方法.
  • 第一、二步,是在第一次访问的时候 创建Servlet程序时调用。只会执行一次
  1. 执行service方法.
  • 第三步,每次访问都会调用。(每次刷新也算是每次访问)
  1. 执行destroy销毁方法.
  • 第四步,在web工程停止的时候调用。

2、通过继承HttpServlet实现Servlet程序

  • 一般在实际项目开发中,都是使用继承HttpServlet类的方式去实现Servlet程序。
  • 具体步骤:
  1. 编写一个类去继承HttpServlet类
  2. 根据业务需要重写doGetdoPost方法
  3. 到web.xml中去配置Servlet程序的访问地址
Servlet程序
public class HttpsServlet extends HttpServlet {
    /**
     * doGet() 在get请求的时候调用 -> 动态绑定
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这个get请求过来的内容..");
    }

    /**
     * doPost() 在post请求的时候调用 -> 动态绑定
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post请求过来的内容..");
    }
}
web.xml
<servlet>
     <servlet-name>hs</servlet-name>
     <servlet-class>com.rnny.servlet.HttpsServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>hs</servlet-name>
    <url-pattern>/hs</url-pattern>
</servlet-mapping>

ServletConfig类

基本介绍

  • ServletConfig类从类名上来看,就知道是Servlet程序的配置信息类
  • Servlet程序和ServletConfig对象都是Tomcat负责创建,我们负责使用。
  • Servlet程序默认是第一次访问的时候创建,ServletConfig每个Servlet程序创建时,就创建一个对应的ServletConfig对象

ServletConfig类的三大作用

  1. 可以获取web.xml中配置的Servlet程序的别名 servlet-name 的值.
  2. 获取web.xml中配置的初始化参数 init-param. init-param是在servlet标签里面的.
  3. 获取ServletContext 对象.
servlet程序
@Override
public void init(ServletConfig servletConfig) throws ServletException {
    System.out.println("2、init初始化方法");

    // 1、 可以获取 Servlet 程序的别名 servlet-name 的值
    String servletName = servletConfig.getServletName();
    // HelloServlet程序的别名 -> HelloServlet
    System.out.println("HelloServlet程序的别名 -> " + servletName);
    // 2、 获取初始化参数 init-param
    String username = servletConfig.getInitParameter("username");
    // 初始化参数username的值 -> root
    System.out.println("初始化参数username的值 -> " + username);
    String url = servletConfig.getInitParameter("url");
    // 初始化参数url的值 -> jdbc:mysql://localhost:3306/test
    System.out.println("初始化参数url的值 -> " + url);
    // 3、 获取 ServletContext 对象
    // org.apache.catalina.core.ApplicationContextFacade@63eb024
    System.out.println(servletConfig.getServletContext());
}
web.xml
<servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.rnny.servlet.HelloServlet</servlet-class>
    
    <!-- init-param 是初始化参数 -->
    <init-param>
        <!-- param-name 是 参数名 -->
        <param-name>username</param-name>
        <!-- param-value是 参数值 -->
        <param-value>root</param-value>
    </init-param>
    <!-- init-param 是初始化参数 -->
    <init-param>
        <!-- param-name 是 参数名 -->
        <param-name>url</param-name>
        <!-- param-value是 参数值 -->
        <param-value>jdbc:mysql://localhost:3306/test</param-value>
    </init-param>
    
</servlet>
<servlet-mapping>
    <servlet-name>HelloServlet</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

细节

  • 重写init方法里面一定要调用父类init(ServletConfig)操作
public class HelloServlet2 extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        // 重写init方法里面一定要调用父类的init(ServletConfig)操作
        super.init(config);
        System.out.println("重写了init初始化方法, 做了一些工作");
    }
}

ServletContext类

基本介绍

  1. ServletContext 是一个接口,它表示Servlet上下文对象
  2. 一个web工程,只有一个ServletContext对象实例。不管你调用多少次getServletContext(); 方法,返回的都是同一个ServletContext对象这点和ServletConfig一点也不类似
  3. ServletContext对象是一个域对象.
  4. ServletContext在web工程部署启动的时候创建在web工程停止的时候销毁

域对象

  • 域对象,是可以像Map一样存取数据的对象,叫域对象。
  • 这里的域指的是存取数据的操作范围,即整个web工程
存数据 取数据 删除数据
Map put() get() remove()
域对象 setAttribute() getAttribute() removeAttribute()

ServletContext类的四个作用

  1. 获取web.xml中配置的上下文参数 context-param.
  2. 获取当前的工作路径,格式:/工作路径.
  3. 获取工程部署后在服务器硬盘上的绝对路径.
  4. 像Map一样存取数据.
servlet程序
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 获取ServletContext对象
    ServletContext context = getServletConfig().getServletContext();// 方式1
    context = getServletContext();// 方式2

    // 1、 获取 web.xml 中配置的上下文参数 context-param
    String username = context.getInitParameter("username");
    // context-param参数username的值是->context
    System.out.println("context-param参数username的值是->" + username);
    // context-param参数password的值是->root
    System.out.println("context-param参数password的值是->" + context.getInitParameter("password"));
    
    // 2、 获取当前的工程路径, 格式: /工程路径
    // 当前工作路径->/web06
    System.out.println("当前工作路径->" + context.getContextPath());
    
    // 3、 获取工程部署后在服务器硬盘上的绝对路径
    /**
     *  / 斜杠被服务器解析地址为:http://ip:port/工程名/ 
     *				映射到 IDEA 代码的 web 目录<br/>
     */
    // 工程部署的路径是->D:\javaweb\web01\out\artifacts\web06_war_exploded\
    System.out.println("工程部署的路径是->" + context.getRealPath("/"));
    
    // 工程下css目录的绝对路径是->D:\javaweb\web01\out\artifacts\web06_war_exploded\css
    System.out.println("工程下css目录的绝对路径是->" + context.getRealPath("/css"));
    
    // 工程下imgs目录下的temp.jpg绝对路径是->D:\javaweb\web01\out\artifacts\web06_war_exploded\imgs\temp.jpg
    System.out.println("工程下imgs目录下的temp.jpg绝对路径是->" + context.getRealPath("/imgs/temp.jpg"));
    
    // ServletContext 像 Map 一样存取数据(域数据,共享数据)
    Object key1 = context.getAttribute("key1");
    System.out.println("保存之前,获取key1的值是:" + key1);
    context.setAttribute("key1", "value1");
    System.out.println("设置之后,获取域数据key1 -> " + context.getAttribute("key1"));
}
web.xml
<!-- context-param -->
<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
    <param-name>username</param-name>
    <param-value>context</param-value>
</context-param>
<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
    <param-name>password</param-name>
    <param-value>root</param-value>
</context-param>

<!-- servlet配置 -->
<servlet>
    <servlet-name>ContextServlet</servlet-name>
    <servlet-class>com.rnny.servlet.ContextServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ContextServlet</servlet-name>
    <url-pattern>/contextServlet</url-pattern>
</servlet-mapping>

ServletConfig 与 ServletContext关系示意图

image-20220507095322873.

HTTP协议

基本介绍

  • 什么是协议?
    • 协议是指双方,或多方,相互约定好的,大家都需要遵守的规则,叫协议。
  • 所谓HTTP协议,就是指 客户端和服务器之间通信时,发送的数据,都需要遵守的规则,叫HTTP协议
  • HTTP协议中的数据又叫报文

HTTP协议格式

  • 客户端给服务器发送数据叫请求 request。

  • 服务器给客户端回传数据叫响应 response。

  • 请求又分为GET请求,和POST请求两种.

请求

GET请求

  1. 请求行.
    • 请求的方式/方法 GET
    • 请求的资源路径[+?+请求参数]
    • 请求的协议和版本号 HTTP/1.1
  2. 请求头.
    • key: value 组成 不同的键值对,表示不同的含义

需要知道的GET请求头

  • Accept:告诉服务器,客户端可以接收的数据类型。
  • Accept-Language:告诉服务器客户端可以接收的语言类型。
    • zh_CN 中文中国
    • en_US 英文美国
  • User-Agent:浏览器的信息
  • Accept-Encoding:告诉服务器,客户端可以接收的数据编码(压缩)格式。
  • Host:表示请求的服务器ip和端口号
  • Connection

POST请求

  1. 请求行.

    • 请求的方式/方法 POST
    • 请求的资源路径[+?+请求参数]
    • 请求的协议和版本号 HTTP/1.1
  2. 请求头.

    • key: value 不同的请求头,有不同的含义

    空行

  3. 请求体. ===>>> 就是发送给服务器的数据.

需要知道的POST请求头

.......

常用请求头的说明

  • Accept:表示客户端可以接收的数据类型.
  • Accept-Language:表示客户端可以接收的语言类型.
  • User-Agent:表示客户端浏览器的信息.
  • Host:表示请求时的服务器ip和端口号.

GET请求与POST请求

GET请求
  1. form标签 method=get.
  2. a标签
  3. link标签引入css
  4. Script标签引入js文件
  5. img标签引入图片
  6. iframe引入html页面
  7. 在浏览器地址栏中输入地址后敲回车.
POST请求
  1. form 标签 method=post.

响应

响应的HTTP协议格式

  1. 响应行.

    • 响应的协议和版本号 HTTP/1.1
    • 响应状态码 200等等
    • 响应状态描述符 OK等等
  2. 响应头.

    • key: value 不同的响应头,有其不同的含义

    空行.

  3. 响应体.===>>> 就是回传给客户端的数据.

响应示意图

.......

常用的响应码说明

  • 200 表示请求成功.
  • 302 表示请求重定向.
  • 404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误).
  • 500 表示服务器已经收到请求,但是服务器内部错误(代码错误).

HttpServletRequest类

基本介绍

  1. 每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中

  2. 然后传递到service方法(doGetdoPost)中给我们使用。我们只需要重写doGet 或 doPost 方法即可 -> 这里用到了动态绑定

  3. 我们可以通过HttpServletRequest对象,获取到所有请求的信息。

常用方法

// 1、获取请求的资源路径
// 格式:/工程名/资源名
request.getRequestURI();
// 2、获取请求的统一资源定位符(绝对路径)
// 格式:http://服务器ip:port/工程名/资源名
request.getRequestURL();
// 3、获取客户端的ip地址
request.getRemoteHost();
// 获取请求头
request.getHeader(String);
// 获取请求的参数
request.getParameter(String);
// 获取请求的参数(多个值的时候使用)
request.getParameterValues(String);
// 获取请求的方式/方法(GET或POST)
request.getMethod();
// 设置域数据
request.setAttribute(key, value);
// 获取域数据
request.getAttribute(key);
// 获取请求转发对象
request.getRequestDispatcher();

示例代码

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1、获取请求的资源路径
    // 格式:/工程名/资源名
    // /web07/requestAPIServlet02
    System.out.println("URI -> " + request.getRequestURI());
    // 2、获取请求的统一资源定位符(绝对路径)
    // 格式:http://服务器ip:port/工程名/资源名
    // http://localhost:8080/web07/requestAPIServlet02
    System.out.println("URL -> " + request.getRequestURL());
    // 3、获取客户端的ip地址
    /*
      在IDEA中, 使用localhost访问时,得到客户端ip地址是 -> 0:0:0:0:0:0:0:1
      在IDEA中, 使用127.0.0.1访问时,得到客户端ip地址是 -> 127.0.0.1
      在IDEA中, 使用 真实ip 访问时,得到客户端ip地址是 -> 真实的客户端ip地址
    */
    System.out.println("客户端ip -> " + request.getRemoteHost());
    // 4、获取请求头
    System.out.println("服务器host -> " + request.getHeader("host"));
    System.out.println("服务器Host -> " + request.getHeader("Host"));
    System.out.println("客户端user-agent -> " + request.getHeader("user-agent"));
    System.out.println("客户端accept-language -> " + request.getHeader("accept-language"));
    System.out.println("客户端accept -> " + request.getHeader("accept"));
    // 获取请求的方式/方法(GET或POST) 强制必须全大写
    System.out.println("请求方式 -> " + request.getMethod());
}

获取请求参数

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 获取请求的参数
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    System.out.println("username -> " + username);
    System.out.println("password -> " + password);
    // 获取请求的参数(多个值的时候使用)
    String[] hobbies = request.getParameterValues("hobby");
    System.out.println("hobby -> " + Arrays.toString(hobbies));
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/web07/requestAPIServlet02" method="get">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    爱好:<input type="checkbox" name="hobby" value="java">java
        <input type="checkbox" name="hobby" value="cpp">c++
        <input type="checkbox" name="hobby" value="js">js
    <br>
    <input type="submit">
</form>
</body>
</html>

POST请求解决中文乱码

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 设置请求体的字符集为utf-8,从而解决post请求的中文乱码问题
    request.setCharacterEncoding("utf-8");

    System.out.println("------doPost...------");
    // 获取请求的参数
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    System.out.println("username -> " + username);
    System.out.println("password -> " + password);
    // 获取请求的参数(多个值的时候使用)
    String[] hobbies = request.getParameterValues("hobby");
    System.out.println("hobby -> " + Arrays.toString(hobbies));
}

请求转发

  • 请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发
// req.getRequestDispatcher(String path)方法
// 1、如果以"/"开头 -> / 斜杠代表 http://ip:port/工程名/  映射到IDEA代码的web目录
// 2、如果以"/"开头 ->  此时代表的目录是 http://ip:port/工程名/ 映射到IDEA代码的web目录
// 由1和2可知 请求转发无法访问工程以外的资源

image-20220510160553073.

示例代码
// ServletTest1
public class ServletTest1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1、获取请求的参数(办事的材料) 查看
        String username = req.getParameter("username");
        System.out.println("1、在ServletTest1 (柜台1) 中查看参数(材料) -> " + username);

        // 2、给材料盖一个章,并传递到ServletTest2(柜台2)去查看
        // 它们共享Request域中的数据
        req.setAttribute("key1", "柜台1的章");

        // 3、问路:ServletTest2 (柜台2) 怎么走
        /*
            请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/
                映射到IDEA代码的web目录
         */
        // Dispatcher 调度、调度器
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servletTest2");
        // 可以转发到WEB-INF目录下
        // RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/form.html");
        // 不可以访问工程以外的资源
        // RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.baidu.com");

        // 4、走向ServletTest2 (柜台2)
        // 它们是一次请求
        requestDispatcher.forward(req, resp);
    }
}
// ServletTest2
public class ServletTest2 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1、获取请求的参数(办事的材料) 查看
        String username = req.getParameter("username");
        System.out.println("在ServletTest2 (柜台2)中查看材料 -> " + username);

        // 2、查看是否有柜台1的章
        Object key1 = req.getAttribute("key1");
        System.out.println("是否有柜台1的章 -> " + key1);

        // 3、处理自己的业务
        System.out.println("ServletTest2 处理自己的业务。。。");
    }
}
核心代码段
// 3、问路:ServletTest2 (柜台2) 怎么走
/*
	请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/
	映射到IDEA代码的web目录
*/
// Dispatcher 调度、调度器
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servletTest2");

// 4、走向ServletTest2 (柜台2)
requestDispatcher.forward(req, resp);

base标签的作用

  • base标签 可以设置当前页面所有相对路径工作时,参照哪个路径来进行跳转。
  • 相对路径工作原理
    • 所有相对路径在工作的时候都会按照当前浏览器地址栏中的地址来进行跳转
  • 示意图:

image-20220513113112284.

image-20220513113216880.

image-20220513113237296.

示例代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--
        注意:
         (1) base标签 在 head标签下
         (2) base标签 设置当前页面相对路径工作时参照的地址
         (3) href属性 href属性值就是参照的地址值
         (4) "http://localhost:8080/web07/a/b/"(最后有 /) 表示b是文件夹
             "http://localhost:8080/web07/a/b"(最后没有 /) 表示b是文件
    -->
    <base href="http://localhost:8080/web07/a/b/">
</head>
<body>
<a href="../../index.html">回到首页</a>
</body>
</html>

Web中的相对路径和绝对路径

  • 在javaweb中,路径分为相对路径和绝对路径两种:

    • 相对路径是:

      . 表示当前目录

      .. 表示上一级目录

      资源名 表示当前目录/资源名

    • 绝对路径

      http://ip:port/工程路径/资源路径

  • 在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。

    1. 绝对路径
    2. base + 相对路径

Web中 / 斜杠的不同意义

  • web/ 斜杠 是一种绝对路径
  • / 斜杠 如果被浏览器解析,得到的地址是:http://ip:port/
    • <a href="/">斜杠</a>
  • / 斜杆 如果被服务器解析,得到的地址是:http://ip:port/工程路径
    • <url-pattern>/servlet1</url-pattern>
    • servletContext.getRealPath("/");
    • request.getRequestDispatcher("/");
  • 特殊情况respond.sendRedirect("/"); 服务器把斜杠发送给浏览器解析。得到http://ip:port/

HttpServletResponse类

基本介绍

  • HttpServletResponse类和HttpServletRequest类一样。每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息。
  • 我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse对象来进行设置。

两个输出流的说明

  • 字节流 getOutputStream(); 常用于下载 (传递二进制数据)

  • 字符流 getWriter(); 常用于回传字符串(常用)

  • 注意:两个流同时只能使用一个.

    使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。

往客户端回传数据

public class ResponseIOServlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 要求:往客户端回传 字符串 数据
        // 解决中文乱码问题
        // resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.write("response's content~软柠柠吖");
    }
}

响应的乱码解决

  • 解决响应中文乱码方案一:不推荐使用
// 1、设置服务器字符集为UTF-8
resp.setCharacterEncoding("UTF-8");
// 2、通过响应头,设置浏览器也使用UTF-8字符集
resp.setHeader("Content-Type", "text/html;charset=UTF-8");
  • 解决响应中文乱码方案二:强力推荐.
// 它会同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头
// 提醒注意:此方法一定要在获取流对象之前调用才有效.
resp.setContentType("text/html;charset=UTF-8");

请求重定向

  • 请求重定向,是指客户端给服务器发送请求,然后服务器告诉客户端说,我给你一些地址,你去新地址访问,这就叫请求重定向。(因为之前的地址可能已经被废弃)

image-20220510195813356.

请求重定向的第1种方案
// 1、设置响应状态码 302,表示重定向,(已搬迁)
resp.setStatus(302);
// 2、设置响应头,说明 新的地址在哪里
resp.setHead("Location", "http://localhost:8080");
请求重定向的第2种方案(强力推荐)
resp.sendRedirect("http://localhost:8080");

WebStorm

快捷键

替换

  • Ctrl + R.

查找

  • Ctrl + F.
posted @ 2022-10-24 19:32  软柠柠吖  阅读(26)  评论(0编辑  收藏  举报