目录
1 jQuery库的初次封装
1.1 根据id获取元素
我们学ajax,为啥突然扯到jQuery这个东西?我们发现我们写的ajax的代码很多都是重复的,就想jdbc一样,那么我们是不是也可以写一个工具类来更方便的写Ajax代码呢?那么接下来我们就手动封装一个工具类,这个工具类我们可以把它看做是一个JS的库,名字为jQuery
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
/*要封装的代码是:根据id获取元素,
* 设计思路来自于CSS的语法。#id可以获取到这个元素*/
function jQuery(selector){//selector可能是id选择器也可能是其它,比如class选择器
if (selector.charAt(0) == "#"){
//这表示selector是一个id选择器
var domObj = document.getElementById(selector.substring(1))
return domObj
}
}
$=jQuery
/* window.onload = function (){
document.getElementById("uname").onclick = function (){
document.getElementById("mydiv").innerHTML = "<font color='red'>用户名不存在</font>"
}
}*/
/*window.onload = function (){
jQuery("#uname").onclick = function (){
jQuery("#mydiv").innerHTML = "<font color='red'>用户名不存在</font>"
}
}*/
window.onload = function (){
$("#uname").onclick = function (){
$("#mydiv").innerHTML = "<font color='red'>用户名不存在-----</font>"
}
}
</script>
<button id="uname">显示用户名</button>
<div id="mydiv"></div>
</body>
</html>
需要注意的是,这是我们再传入选择器不是只传入值即可,而是要在前面加上它是什么选择器,比如本次用到的id原则器需要再值前面加上#
1.2 封装window.load
<script type="text/javascript">
function jQuery(selector){//selector可能是id选择器也可能是其它,比如class选择器
if (typeof selector == "string"){
if (selector.charAt(0) == "#"){
//这表示selector是一个id选择器
var domObj = document.getElementById(selector.substring(1))
return domObj
}
}
if (typeof selector == "function"){
window.onload = selector
}
}
$=jQuery
$(function (){
$("#uname").onclick = function (){
$("#mydiv").innerHTML = "<font color='red'>用户名不存在#!&^#&</font>"
}
})
</script>
喵啊
1.3 封装click和html函数
<script type="text/javascript">
function jQuery(selector){//selector可能是id选择器也可能是其它,比如class选择器
if (typeof selector == "string"){
if (selector.charAt(0) == "#"){
//这表示selector是一个id选择器
domObj = document.getElementById(selector.substring(1))
return new jQuery()
}
}
if (typeof selector == "function"){
window.onload = selector
}
this.html = function (htmlStr){
domObj.innerHTML = htmlStr
}
this.click = function (fun){
domObj.onclick = fun
}
}
$=jQuery
$(function (){
$("#uname").click(function (){
$("#mydiv").html("<font color='red'>用户名不存在hfevmk</font>")
})
})
</script>
1.4 封装val方法
这样我们可以在文本框输入信息,还可以在代码中修改value值
this.val = function (v){
if (v == null){
//return domObj.value
return domObj.value
}else {
domObj.value = v
}
}
alert($("#username").val())
$("#username").val("heheh")
1.5 将jQuery文件单独放在js目录下然后引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript" src="js/jQuery-1.0.0.js"></script>
<script type="text/javascript">
$(function (){
$("#uname").click(function (){
$("#mydiv").html("<font color='red'>用户名不存在hfevmk</font>")
//var username = document.getElementById("username").value
//alert(username)
alert($("#username").val())
$("#username").val("heheh")
})
})
$(function (){
$("#btn").click(function (){
$("#mydiv").html("你好,jQuery")
})
})
</script>
<button id="btn">你好</button>
<div id="mydiv"></div>
</body>
</html>
后面就不想封装了,我已经被绕晕了,焯。。
2 Ajax实现省市联动
什么是省市联动,选择对应的省份之后,动态的关联出该省份对应的市。
首先要设计数据库表,注意城市外键的设置和省份的编号对应
先实现动态展示省份
再实现动态展示对应的城市,我们使用onchange事件,当我们选择一个省份的时候,就发出它的编码,这个编码就是城市的外键,然后后端得到这个编码,根据这个编码查询城市然后响应给前端,这部分就和响应省份几乎一模一样了。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>省市联动</title>
</head>
<body>
<script type="text/javascript">
window.onload = function (){
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function (){
if (xhr.readyState == 4){
if (xhr.status == 200){
var areaList = JSON.parse(this.responseText)
var html = "<option value=''>--请选择省份--</option>"
for (var i = 0; i < areaList.length; i++) {
var area = areaList[i]
html += "<option value='"+area.code+"'>"+area.name+"</option>"
}
document.getElementById("province").innerHTML = html
}else {
alert(xhr.status)
}
}
}
xhr.open("GET","/ajax/ajaxrequest10",true)
//4.发送请求
xhr.send()
document.getElementById("province").onchange = function (){
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function (){
if (xhr.readyState == 4){
if (xhr.status == 200){
var areaList = JSON.parse(this.responseText)
var html = "<option value=''>--请选择城市--</option>"
for (var i = 0; i < areaList.length; i++) {
var area = areaList[i]
html += "<option value='"+area.code+"'>"+area.name+"</option>"
}
document.getElementById("city").innerHTML = html
}else {
alert(xhr.status)
}
}
}
xhr.open("GET","/ajax/ajaxrequest10?pcode="+this.value,true)
//4.发送请求
xhr.send()
}
}
</script>
<select id="province">
</select>
<select id="city">
</select>
</body>
</html>
package com.itzw.ajax.servlet;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.odps.udf.CodecCheck;
import com.itzw.ajax.bean.Area;
import com.itzw.ajax.bean.Student;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/ajaxrequest10")
public class AjaxServlet7 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
String pcode = request.getParameter("pcode");
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
String jsonStr = "";
List<Area> areaList = new ArrayList<>();
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url, user, password);
//获取预编译的数据库操作对象
if (pcode == null){
String sql = "select code,name from t_area where pcode is null ";
ps = conn.prepareStatement(sql);
}else {
String sql = "select code,name from t_area where pcode = ? ";
ps = conn.prepareStatement(sql);
ps.setString(1,pcode);
}
//执行SQL语句
rs = ps.executeQuery();
//处理结果集
while (rs.next()){
String code = rs.getString("code");
String name = rs.getString("name");
Area a = new Area(code,name);
areaList.add(a);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//将list集合转为JSON字符串
jsonStr = JSON.toJSONString(areaList);
out.print(jsonStr);
}
}
3 Ajax跨域问题
3.1 跨域概述
- 跨域是从一个域名的网页去请求另一个域名的资源。比如从百度页面去请求京东的资源。
- 经过测试,通过超链接、form表单、window.location.href这种方式进行跨域请求不存在问题。但是使用ajax请求访问就会出现问题,无法跨域访问。
- 这是为什么呢,我们发现,超链接、form表单这种方式都是请求一个新页面,会跳转页面,不会局部刷新。而ajax请求是通过浏览器中的XMLHttpRequest对象来访问的,而跨域就要求两个域要共享这个对象,但是共享XMLHttpRequest对象是不安全的。
- 阻止ajax访问的策略叫同源策略,它是一种安全策略。假如没有这个策略,当我们登录银行这种网页,再登录不规范的网页,那么银行页面就会被访问,这样极不安全。
- 什么是同源呢:协议一致,域名一致,端口号一致才是同源。否则就是不同源,而只有同源才能共享XMLHttpRequest对象,才能访问资源
3.2 解决ajax跨域问题
3.2.1 设置响应头
//设置响应头,允许ajax跨域请求
response.setHeader("Access-Control-Allow-Origin","http://localhost:8081");
3.2.2 jsonp
- jsonp:带填充的json
- jsonp不是一个真正的ajax请求,但是它可以完成ajax的局部刷新效果,并且可以解决跨域问题
- 注意:jsonp解决跨域的时候,只支持GET请求,不支持post请求
下面的方式就可以实现跨域访问,但是还没实现局部刷新
<script type="text/javascript">
function test(data){
//alert("你好测试")
alert(data.name)
}
</script>
<script type="text/javascript" src="http://localhost:8080/b/jsonp">
</script>
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
System.out.println("jsonp完成跨域访问");
//out.print("alert(41647)");
out.print("test({\"name\":\"张三\"})");
}
jsonp解决跨域问题,达到局部刷新效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--<script type="text/javascript" src="http://localhost:8080/b/jsonp"></script>-->
<script type="text/javascript">
function test(data){
//alert("你好测试")
alert(data.name)
}
window.onload = function (){
document.getElementById("btn").onclick = function (){
//创建script元素对象
var htmlScriptElement = document.createElement("script")
//设置script的type属性
htmlScriptElement.type = "text/javascript"
//设置script的src属性
htmlScriptElement.src = "http://localhost:8080/b/jsonp"
//将script对象添加到body标签中(加载script)因为只有一个body,取0下标就可以
document.getElementsByTagName("body")[0].append(htmlScriptElement)
}
}
</script>
<button id="btn">ajax实现局部刷新</button>
</body>
</html>
3.2.3 jQuery封装的jsonp
这段有点听不懂。。。主要是前面的jQuery的封装没咋听懂。。
3.2.4 代理机制
我们在一个站点想访问另一个站点的servlet,不能直接访问,但我们可以先访问本站的servlet,然后本站的servlet再发送请求给另一个站点的servlet。相当于找个中介,问题所在就是本站的servlet怎么发送请求?
有两种方法使用java程序发送get/post请求:
- 第一种:使用JDK内置的API(java.net.URL...),这些API是可以发送HTTP请求的
- 第二种:使用第三方开源组件,比如:Apache的httpclient组件
具体怎么操作,先不操作了。。后面这部分有点小复杂
4 Ajax实现搜索联想自动补全
实现原理:
- 当键盘时间发生之后,比如keyup:弹起事件
- 发送ajax请求,请求中提交用户输入的搜索内容,例如:北京
- 后端接收ajax请求,接收“北京”两个字,执行select语句进行模糊查询,返回查询结果
- 将查询结果封装成JSON格式的字符串,将JSON格式字符串响应到前端
- 前端接收到的JSON格式的字符串之后,解析这个JSON字符串,动态展示页面
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.userInput{
width: 300px;
height: 25px;
font-size: 20px;
}
.showDataDiv{
width: 305px;
border: 1px solid lightgray;
display: none;
}
.showDataDiv p {
margin-top: 5px;
margin-bottom: 5px;
}
.showDataDiv p:hover{
cursor: pointer;
border: 1px blue solid;
background-color: lightgray;
}
</style>
</head>
<body>
<script type="text/javascript">
window.onload = function (){
document.getElementById("keywords").onkeyup = function (){
if (this.value == ""){
document.getElementById("showDataDiv").style.display = "none"
}else {
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.onreadystatechange = function (){
if (this.readyState == 4){
if (this.status >= 200 && this.status < 300){
//[{"content":"javascript"},{"content":"javaweb"}]
var json = JSON.parse(this.responseText);
//遍历数组
var html = ""
for (var i = 0; i <json.length; i++) {
html +="<p onclick='setInput(\""+json[i].content+"\")'>"+json[i].content+"</p>"
}
document.getElementById("showDataDiv").innerHTML = html
document.getElementById("showDataDiv").style.display = "block"
}else {
alert(this.status)
}
}
}
xmlHttpRequest.open("GET","/auto/blurselect?keywords="+this.value,true)
xmlHttpRequest.send()
}
}
}
function setInput(keywords){
document.getElementById("keywords").value = keywords
document.getElementById("showDataDiv").style.display = "none"
}
</script>
<input type="text" class="userInput" id="keywords">
<div class="showDataDiv" id="showDataDiv">
<!-- <p>北京天气</p>
<p>北京疫情</p>
<p>北京高铁</p>
<p>北京人</p>
<p>北京朝阳</p>-->
</div>
</body>
</html>
package com.itzw.ajax.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/blurselect")
public class AutoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String keywords = request.getParameter("keywords");
StringBuilder sb = new StringBuilder();
sb.append("[");
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url, user, password);
//获取预编译的数据库操作对象
String sql = "select content from t_ajax where content like ?";//模糊查询
ps = conn.prepareStatement(sql);
ps.setString(1,keywords + "%");//模糊查询在后面加百分号
//执行SQL语句
rs = ps.executeQuery();
//处理结果集
while (rs.next()){
//[{"content":"javascript"},{"content":"javaweb"}]
String content = rs.getString("content");
sb.append("{\"content\":\""+content+"\"},");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
response.getWriter().print(sb.substring(0,sb.length()-1)+"]");
}
}