文章目录
1. 前后端交互
web开发分为前端和后端。
- 前端是面向用户的一端,即浏览器程序开发。
- 后端则是为前端提供服务,即服务器程序开发。
Node内置有web服务器。
在动态网站中,许多功能是由前后端交互实现的。
- eg:用户注册和登录、发表评论、查询积分等
前后端操作分为两类:
- 向服务器提交数据(表单交互)
- 向服务器查询数据(URL参数交互)
表单交互:
- 指在HTML中创建一个表单,用户填写表单后提交给服务器,服务器收到表单后返回处理结果。
URL参数交互:
- 用于浏览器向服务器提交一些请求信息。
- 例如:http://localhost:3000/index?username=张三&gender=男
2. Ajax
2.1 Ajax概述
Ajax:Asynchronous JavaScript And XML,异步JavaScript和XML技术。
在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法。
包括: HTML 或 XHTML, CSS, JavaScript, DOM, XML, XSLT, 以及最重要的XMLHttpRequest。
使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。
功能: 用于实现与服务器进行异步交互的功能。
- 不刷新页面更新网页
- 在页面加载后从服务器请求数据
- 在页面加载后从服务器接收数据
- 在后台向服务器发送数据
- AJAX
提供与服务器异步通信的能力,可以在Web页面触发的JavaScript事件中向服务器发出异步请求,执行更新或查询数据库。
- AJAX的
核心是JavaScript对象XMLHttpRequest
,该对象在IE 5中首次引入,使用户通过JavaScript向服务器提出请求并处理响应,而不阻塞用户。通过这个对象,您的 JavaScript 可在不重载页面的情况与 Web 服务器交换数据,即在不需要刷新页面的情况下,就可以产生局部刷新的效果。- 当Web服务器的响应返回时,使用JavaScript回调函数和CSS来相应地
更新页面的局部内容
,而不是刷新整个页面。- 在页面与服务器交互的过程中不中断用户操作,
用户甚至察觉不到浏览器正在与服务器通信
。
优势:
- 减轻服务器的负担
- 节省带宽
- 用户体验更好
2.2 Ajax如何工作
- 网页中发生了一个事件(页面加载、按钮点击)
- 由JavaScript创建XMLHttpRequest对象
- XMLHttpRequest对象通过open()方法建立对服务器的调用、设置回调函数 、调用send()方法向web服务器发送请求
- 服务器处理该请求
- 服务器将响应发送回网页
- 由JavaScript读取响应
- 由JavaScript执行正确的动作(比如更新页面)
2.3 XMLHttpRequest对象
Ajax 的核心是 XMLHttpRequest 对象。
- 所有现代浏览器都支持 XMLHttpRequest 对象。
- XMLHttpRequest 对象用于同幕后服务器交换数据。这意味着可以更新网页的部分,而不需要重新加载整个页面。
创建XMLHttpRequest对象:
- 所有现代浏览器(Chrom、IE7+、Firefox、Safari 以及 Opera)都有内建的 XMLHttpRequest 对象。创建 XMLHttpRequest 的语法是:
variable = new XMLHttpRequest();
- 老版本的 Internet Explorer(IE5 和 IE6)使用 ActiveX 对象:
variable = new ActiveXObject("Microsoft.XMLHTTP")
注:为了应对所有浏览器,包括 IE5 和 IE6,请检查浏览器是否支持 XMLHttpRequest 对象。如果支持,创建 XMLHttpRequest 对象,如果不支持,则创建 ActiveX 对象:
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
XMLHttpRequest 对象方法:
new XMLHttpRequest()
:创建新的 XMLHttpRequest 对象abort()
:取消当前请求getAllResponseHeaders()
:返回头部信息getResponseHeader()
:返回特定的头部信息open(method, url, async, user, psw)
:
method:请求类型 GET或POST
url:文件位置
async:true(异步)或 false(同步)
user:可选的用户名称
psw:可选的密码send()
:将请求发送到服务器,用于 GET 请求send(string)
:将请求发送到服务器,用于 POST 请求setRequestHeader()
:向要发送的报头添加标签/值对
XMLHttpRequest 对象属性:
onreadystatechange
:定义当 readyState 属性发生变化时被调用的函数readyState
:
保存 XMLHttpRequest 的状态。
0:请求未初始化
1:服务器连接已建立
2:请求已收到
3:正在处理请求
4: 请求已完成且响应已就绪responseText
:以字符串返回响应数据responseXML
:以 XML 数据返回响应数据status
:返回请求的状态号
200: “OK”
403: “Forbidden”
404: “Not Found”statusText
:返回状态文本(比如 “OK” 或 “Not Found”)
2.4 使用Ajax
eg: form表单中的值提交到后台 后台存入数据库
ajax底层使用:
<script>
//获取XMLHTTPRequest对象
function getXmlHttpRequest(){
let xmlHttpRequest;
if(window.ActiveXObject){//若是IE浏览器
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}else if(window.XMLHttpRequest){//非IE浏览器
xmlHttpRequest = new XMLHttpRequest();
}
return xmlHttpRequest;
}
//通过XMLHttpRequest对象向后台发送异步请求
function getServerInfo() {
//获取Ajax的核心对象
let httpRequest = getXmlHttpRequest();
//获取表单数据
let name = document.getElementById('emp_name').value;
let gender = document.getElementById('emp_gender').value;
let birthday = document.getElementById('emp_birthday').value;
let phone = document.getElementById('emp_phone').value;
let address = document.getElementById('emp_address').value;
// 拼接要发送的值
let post_str = 'emp_name='+name+'&emp_gender='+gender+'&emp_birthday='+birthday+'&emp_phone='+phone+'&emp_address='+address;
//调用open()方法建立与服务器的连接
httpRequest.open('post','http://localhost:3000/index',true);
//设置请求头信息
httpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//设置请求-响应状态发生改变时的回调函数
httpRequest.onreadystatechange = function () {
if(httpRequest.readyState == 4 && httpRequest.status == 200){//请求-响应成功完成
//获取响应信息
let info = httpRequest.responseText;
//将获取到的响应信息写入到页面的span标签中
document.getElementById('msg').innerHTML = info;
}
}
//向服务器发送请求
httpRequest.send(post_str);
}
</script>
jquery对ajax的封装:
需要引入jquery库
$.ajax({
url: '远程服务器的地址',
type: '请求方式',
data: '发送给服务器端的数据',
dataType: '服务器返回的数据的格式',
success: function(data) {
//请求成功后的回调函数,参数data中放的是服务器的响应数据
},
error: function(err) {
//请求失败的回调函数,参数"err"中放的是错误信息
}
})
<script>
$(function () {
$('#btn_ok').click(function () {
$.ajax({
url: 'http://localhost:3000/index',
type: 'post',
data: $('form').serialize(), //表单序列化:将表单控件的值拼接成字符串
dataType: 'json',
success: function (result) {
$('#msg').html(result.info);
}
})
});
})
</script>
jquery对ajax的高层封装:
需要引入jquery库*
只能进行post请求:
$post(url,[data],[callback],[type])
url:发送请求的地址
data:待发送的key/value参数
callback:发送成功时的回调函数
type:返回的内容格式:xml、html、script、json、text等
let obj = {
name: 'AAA',
age: 24,
gender: '男'
};
$post("http://localhost:3000/index",obj,function(result){'成功后的处理代码'},'json')
只能进行get请求:
$get(url,[data],[callback],[type])
url:发送请求的地址
data:待发送key/value参数
callback:发送成功时的回调函数
type:返回的内容格式:xml、html、script、json、text等
eg:使用ajax实现页面的数据通过Node后台提交到数据库
使用ajax涉及到跨域问题,需要注意
项目结构:
- dbconfig.js
//导入mysql模块
const mysql = require('mysql2');
//创建数据库连接对象
const connection = mysql.createConnection({
host:'localhost',
port:3306,
user:'root',
password:'*****',
database:'deyun'
})
//让数据库的连接对象对外可见
module.exports = connection;
- client.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:3000/index" method="post">
姓名:<input type="text" name="emp_name" id="emp_name"><br><br>
性别:<input type="text" name="emp_gender" id="emp_gender"><br><br>
生日:<input type="date" name="emp_birthday" id="emp_birthday"><br><br>
电话:<input type="text" name="emp_phone" id="emp_phone"><br><br>
地址:<input type="text" name="emp_address" id="emp_address"><br><br>
<input type="button" value="提交" onclick="getServerInfo()">
</form>
<br><br>
<span id="msg" style="color:red;font-size:20px"></span>
<script>
//获取XMLHTTPRequest对象
function getXmlHttpRequest(){
let xmlHttpRequest;
if(window.ActiveXObject){//若是IE浏览器
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}else if(window.XMLHttpRequest){//非IE浏览器
xmlHttpRequest = new XMLHttpRequest();
}
return xmlHttpRequest;
}
//通过XMLHttpRequest对象向后台发送异步请求
function getServerInfo() {
//获取Ajax的核心对象
let httpRequest = getXmlHttpRequest();
//获取表单数据
let name = document.getElementById('emp_name').value;
let gender = document.getElementById('emp_gender').value;
let birthday = document.getElementById('emp_birthday').value;
let phone = document.getElementById('emp_phone').value;
let address = document.getElementById('emp_address').value;
// 拼接要发送的值
let post_str = 'emp_name='+name+'&emp_gender='+gender+'&emp_birthday='+birthday+'&emp_phone='+phone+'&emp_address='+address;
//调用open()方法建立与服务器的连接
httpRequest.open('post','http://localhost:3000/index',true);
//设置请求头信息
httpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//设置请求-响应状态发生改变时的回调函数
httpRequest.onreadystatechange = function () {
if(httpRequest.readyState == 4 && httpRequest.status == 200){//请求-响应成功完成
//获取响应信息
let info = httpRequest.responseText;
//将获取到的响应信息写入到页面的span标签中
document.getElementById('msg').innerHTML = info;
}
}
//向服务器发送请求
httpRequest.send(post_str);
}
</script>
</body>
</html>
服务器未设置跨域访问出现的问题:
- httpserver.js
//导入http模块:用户创建http服务器
const http = require('http');
//导入querystring模块:用来解析客户端提交的数据
const queryString = require('querystring');
//导入数据库的配置模块:用于数据库的操作
const connection = require('../db/dbconfig');
//创建http服务器:对应的请求地址是:http://localhost:3000/index
let server = http.createServer((req,res) => {
//获取客户端请求的地址
let clientUrl = req.url;
console.log(clientUrl);
if (clientUrl === '/index'){
let body = '';//用来保存客户端提交的请求数据
//给请求对象req绑定'data'事件:用来获取客户端的请求数据
req.on('data',chunk => {
body += chunk;
});
//给请求对象req绑定'end'事件
req.on('end',() => {
let params = queryString.parse(body);//将body中的数据转换为键值对的形式
res.setHeader("Content-Type", "application/json;charset=utf-8");
//拼接响应字符串
let res_str = '姓名:'+params.emp_name+"\n"+
'性别:'+params.emp_gender+"\n"+
'生日:'+params.emp_birthday+"\n"+
'电话:'+params.emp_phone+'\n'+
'地址:'+params.emp_address;
console.log(res_str);
//将响应字符串发送给客户端 先把信息写入数据库,再响应给客户端
save(params);
res.write('插入数据成功!');
//关闭连接
res.end();
})
}
})
server.listen(3000);//绑定端口号
//创建将数据保存到数据库的方法
function save(params){
connection.query('insert into employee set ?',{
name:params.emp_name,
gender:params.emp_gender,
birthday:params.emp_birthday,
phone:params.emp_phone,
address:params.emp_address
},(err,result) => {
if(err){
console.log(err);
return;
}
console.log('插入数据成功');
connection.end();//断开数据库的连接
})
}
服务器设置跨域访问:
//导入http模块:用户创建http服务器
const http = require('http');
//导入querystring模块:用来解析客户端提交的数据
const queryString = require('querystring');
//导入数据库的配置模块:用于数据库的操作
const connection = require('../db/dbconfig');
//创建http服务器:对应的请求地址是:http://localhost:3000/index
let server = http.createServer((req,res) => {
//获取客户端请求的地址
let clientUrl = req.url;
console.log(clientUrl);
if (clientUrl === '/index'){
let body = '';//用来保存客户端提交的请求数据
//给请求对象req绑定'data'事件:用来获取客户端的请求数据
req.on('data',chunk => {
body += chunk;
});
//给请求对象req绑定'end'事件
req.on('end',() => {
let params = queryString.parse(body);//将body中的数据转换为键值对的形式
//设置服务器端的响应头信息,实现跨域
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild");
res.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.setHeader("X-Powered-By","3.2.1");
res.setHeader("Content-Type", "application/json;charset=utf-8");
//拼接响应字符串
let res_str = '姓名:'+params.emp_name+"\n"+
'性别:'+params.emp_gender+"\n"+
'生日:'+params.emp_birthday+"\n"+
'电话:'+params.emp_phone+'\n'+
'地址:'+params.emp_address;
console.log(res_str);
//将响应字符串发送给客户端 先把信息写入数据库,再响应给客户端
save(params);
res.write('插入数据成功!');
//关闭连接
res.end();
})
}
})
server.listen(3000);//绑定端口号
//创建将数据保存到数据库的方法
function save(params){
connection.query('insert into employee set ?',{
name:params.emp_name,
gender:params.emp_gender,
birthday:params.emp_birthday,
phone:params.emp_phone,
address:params.emp_address
},(err,result) => {
if(err){
console.log(err);
return;
}
console.log('插入数据成功');
connection.end();//断开数据库的连接
})
}
```![在这里插入图片描述](https://img-blog.csdnimg.cn/d21b49d67690454da974b26ae3b6cfa3.gif#pic_center)