XMLHttpRequest对象
XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest 在 AJAX 编程中被大量使用。
FormData对象
FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send()方法发送出去,
状态码
ajax状态码
在创建ajax对象,配置ajax对象,发送请求,以及接收完服务器端响应数据,这个过程中的每一个步骤都会对应一个ajax状态码。
// 0:请求未初始化(还没有调用open())
// 1:请求已经建立,但是还没有发送还没有调用send()
// 2:请求已经发送
// 3:请求正在处理中,通常响应中已经有部分数据可以用了
// 4:响应已经完成,可以获取并使用服务器的响应了
// xhr.readyState ajax状态码
// xhr.onreadystatechange 状态码改变调用此函数
// xhr.onload 客户端接受服务端的响应数据后触发
// onreadystatechange 函数触发多次,兼容ie浏览器
// onload 函数触发一次,不兼容ie浏览器
// 创建ajax对象
let xhr = new XMLHttpRequest()
// 状态码为0
console.log(xhr.readyState)
// ajax对象以什么方式对哪里发送请求
xhr.open('get', 'http://127.0.0.1:8080')
// 状态码为1
console.log(xhr.readyState)
// ajax对象发送请求
xhr.send()
// 状态码改变时调用此函数
xhr.onreadystatechange = function (){
// 状态码依次改变为 2 3 4
console.log(xhr.readyState)
}
http状态码
- 网络畅通,服务器端能接收到睛求,服务器端返回的结果不是预期结果。可以判断服务器端返回的状态码,分别进行处理。
xhr.status获取http状态码 - 网络畅通,服务器端没有接收到请求,返回 404状态码。检查请求地址是否错误。
- 网络畅通,服务器端能接收到请求,服务器端返回 500状态码。服务器端错误,找后端程序员进行沟通。
- 网络中断,请求无法发送到服务器端。会触发xhr对象下面的
onerror事件,在onerror事件处理函数中对错误进行处理。
ajax使用
get方法
客户端设置
<body>
<button>按钮</button>
<script>
let button = document.querySelector('button');
button.onclick = function () {
// 创建ajax对象
let xhr = new XMLHttpRequest()
// ajax对象以什么方式 对哪里发送请求
xhr.open('get', 'http://127.0.0.1:8080')
// ajax对象发送请求
xhr.send()
// 当客户端接受服务端的响应数据后,会触发onload事件
xhr.onload = function () {
console.log('成功接受到服务端请求')
// 输出服务端返回的响应体
console.log(xhr.responseText)
// 解析响应体的jSON对象
console.log(JSON.parse(xhr.responseText))
}
}
</script>
</body>
服务器设置
const express = require('express')
const app = express()
app.get('/',(req,res)=>{
// 允许所有跨域
res.setHeader('Access-Control-Allow-Origin','*')
// 发送JSON数据
res.send({
name:'kawaii',
age:20
})
})
app.post('/',(req,res)=>{
res.send({
name:'kawaii',
age:20
})
})
app.listen(8080,()=>{
console.log('我监听了8080 http://127.0.0.1:8080')
})
post方法
客户端设置
<body>
<input type="text" name="" id="username">
<input type="text" name="" id="age">
<button>按钮</button>
<script>
// post 请求必须设置请求参数类型
let username = document.querySelector('#username');
let age = document.querySelector('#age');
let button = document.querySelector('button');
button.onclick = function () {
// 合并参数
let params = `username=${username.value}&age=${age.value}`;
// 创建ajax对象
let xhr = new XMLHttpRequest()
// ajax对象以什么方式对哪里发送请求
xhr.open('post', 'http://127.0.0.1:8080')
// 设置请求参数类型
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
// 参数必须在send函数中发出
xhr.send(params)
// 当客户端接受服务端的响应数据后,会触发onload事件
xhr.onload = function () {
console.log('成功接受到服务端请求')
// 输出服务端返回的响应体
console.log(xhr.responseText)
}
}
</script>
</body>
服务器设置
const express = require('express')
const app = express()
// 使用内置模块解析post请求
app.use(express.urlencoded({extended:false}))
app.get('/',(req,res)=>{
// 允许所有跨域
res.setHeader('Access-Control-Allow-Origin','*')
})
app.post('/',(req,res)=>{
// 允许所有跨域
res.setHeader('Access-Control-Allow-Origin','*')
// 返回请求体
res.send(req.body)
})
app.listen(8080,()=>{
console.log('我监听了8080 http://127.0.0.1:8080')
})
post方法(JSON)
客户端设置
<body>
<input type="text" name="" id="username">
<input type="text" name="" id="age">
<button>按钮</button>
<script>
// post 请求必须设置请求参数类型
let username = document.querySelector('#username');
let age = document.querySelector('#age');
let button = document.querySelector('button');
button.onclick = function () {
// 合并参数为JSON对象
let params = {
username:username.value,
age:age.value
}
// 创建ajax对象
let xhr = new XMLHttpRequest()
// ajax对象以什么方式对哪里发送请求
xhr.open('post', 'http://127.0.0.1:8080')
// 设置请求参数类型,application/json会产生预检请求
xhr.setRequestHeader('Content-Type','application/json')
// 参数必须在send函数中发出
xhr.send(JSON.stringify(params))
// 当客户端接受服务端的响应数据后,会触发onload事件
xhr.onload = function () {
console.log('成功接受到服务端请求')
// 输出服务端返回的响应体
console.log(xhr.responseText)
}
}
</script>
</body>
服务器设置
const express = require('express')
const app = express()
// 使用内置模块解析post请求
app.use(express.json())
//设置跨域请求
app.all('*', function (req, res, next) {
//设置请求头
//允许所有来源访问
res.header('Access-Control-Allow-Origin', '*')
//用于判断request来自ajax还是传统请求,解决预检请求
res.header("Access-Control-Allow-Headers", "Content-Type");
next()
})
app.post('/',(req,res)=>{
// 返回请求体
res.send(req.body)
})
app.options('/',(req,res)=>{
// 会输出 "使用了预检请求",因为预检请求会先向服务器发送options请求
console.log('使用了预检请求')
res.send()
})
app.listen(8080,()=>{
console.log('我监听了8080 http://127.0.0.1:8080')
})
FormData使用
传输简单FormData对象
客户端设置
<body>
<!--不用设置actions与methods -->
<form id="form">
<input type="text" name="username" >
<input type="password" name="password" >
<!-- submit会提交表单 -->
<input type="button" id="button" value="提交">
</form>
<script>
let button = document.querySelector('#button');
button.onclick = function (){
// 获取form元素
let form = document.querySelector('#form');
// 将form转换为formData表单对象
let formData = new FormData(form);
// 创建ajax对象
let xhr = new XMLHttpRequest();
// formData不能用于get请求,因为要放在send()中,send(formData)
xhr.open('post','http://localhost:8080')
// 发送ajax对象
xhr.send(formData)
xhr.onload = function (){
// 对http状态码进行检测
if (xhr.status===200){
console.log(xhr.responseText);
}
}
}
</script>
</body>
服务器设置
const express = require('express')
// npm i formidable 引入解析application/json包
const formidable = require('formidable')
const app = express()
//设置跨域请求
app.use((req, res, next)=> {
//设置请求头
//允许所有来源访问
res.setHeader('Access-Control-Allow-Origin', '*')
next()
})
app.post('/',(req,res)=>{
// 创建表单解析对象
const form = new formidable.IncomingForm();
// 解析客户端的formData对象 错误对象,普通请求参数 文件上传信息
form.parse(req,(err,fields,files)=>{
res.send(fields)
})
//表单传递的input数据
form.parse(req, function(err, fields, files) {
console.log('fields',fields);
});
});
app.options('/',(req,res)=>{
console.log('使用了预检请求')
res.send()
})
app.listen(8080,()=>{
console.log('我监听了8080 http://127.0.0.1:8080')
})
传输文件
客户端设置
<body>
<!--不用设置actions与methods-->
<form id="form" enctype="multipart/form-data">
<!-- 挂载图片 -->
<div id="box"></div>
<!-- 文件上传控件 -->
<input type="file" name="file" id="file">
<!-- submit会提交表单 -->
</form>
<script>
let file = document.querySelector('#file')
let box = document.querySelector('#box');
// 当用户选择完文件并确认后触发函数
file.onchange = function (){
// 获取form元素
let form = document.querySelector('#form');
// 将form转换为formData表单对象
let formData = new FormData(form);
console.log(this.files)
// 创建ajax对象
let xhr = new XMLHttpRequest();
// formData不能用于get请求,因为要放在send()中,send(formData)
xhr.open('post','http://localhost:8080')
// xhr 上传时会持续触发onprogress事件
// xhr.upload.onprogress = function (){
// // 显示百分比
// bar.style.width = (ev.loaded/ev.total)*100 + '%'
// }
// 发送ajax对象
xhr.send(formData)
// 客户端接受到服务器响应触发
xhr.onload = function (){
// 对http状态码进行检测
if (xhr.status===200){
// 将字符串解析成JSON对象
let result = JSON.parse(xhr.responseText)
// 创建img标签
let img = document.createElement('img')
// 设置文件的src属性
img.src = result.path
img.width = 300
// 当图片加载完成后插入box中
img.onload = function (){
// img插入box中
box.appendChild(img)
}
}
}
}
</script>
</body>
服务器设置
const express = require('express')
// npm i formidable 引入解析 multipart/form-data包
const { Formidable } = require('formidable')
// 引入path模块
const path = require('path')
const app = express()
//设置跨域请求
app.all('*', function (req, res, next) {
//设置请求头
//允许所有来源访问
res.header('Access-Control-Allow-Origin', '*')
next()
})
app.post('/',(req,res)=>{
console.log('hello post')
// 创建表单解析对象 并保留上传文件夹扩展名
const form = new Formidable({
// 并保留上传文件夹扩展名 必须设置这个filename里的ext才生效,
keepExtensions: true,
// 设置上传文件的路径 绝对路径
uploadDir:path.resolve(__dirname,'uploads'),
// 自定义文件名
filename(name, ext, part, form){
return `${name}${ext}`
}
});
console.log(path.resolve(__dirname,'uploads'))
// 解析客户端的formData对象 错误对象,普通请求参数 文件上传信息
form.parse(req,(err,fields,files)=>{
// 将客户端传过来的文件地址响应给服务端
res.send({
path:files.file.filepath.split('nodejs')[1]
})
})
});
app.listen(8080,()=>{
console.log('我监听了8080 http://127.0.0.1:8080')
})
携带Cookie
客户端设置
<body>
<!--不用设置actions与methods -->
<form id="form" enctype="multipart/form-data">
<input type="text" name="username" >
<button id="button" type="button">发送</button>
</form>
<script>
let button = document.querySelector('#button');
// 当用户选择完文件并确认后触发函数
button.onclick = function (){
// 获取form元素
let form = document.querySelector('#form');
// 将form转换为formData表单对象
let formData = new FormData(form);
// 创建ajax对象
let xhr = new XMLHttpRequest();
// formData不能用于get请求,因为要放在send()中,send(formData)
xhr.open('post','http://localhost:8080')
// 跨域请求携带Cookie
xhr.withCredentials = true;
// 发送ajax对象
xhr.send(formData)
// 客户端接受到服务器响应触发
xhr.onload = function (){
// 打印Cookie
console.log(xhr.responseText)
}
}
</script>
</body>
服务器设置
const express = require('express')
// npm i formidable 引入解析 multipart/form-data包
const { Formidable } = require('formidable')
// 引入cookie解析包
let cookieParser = require('cookie-parser')
// 引入path模块
const path = require('path')
const app = express()
// 使用Cookie解析中间件
app.use(cookieParser())
//设置跨域请求
app.use((req, res, next)=> {
//设置请求头
//允许所有来源访问
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
// 运行携带Cookie
res.setHeader('Access-Control-Allow-Credentials','true')
next()
})
app.post('/',(req,res)=>{
console.log('hello post')
// 获得Cookie对象
console.log('Cookies: ', req.cookies)
// 创建表单解析对象 并保留上传文件夹扩展名
const form = new Formidable();
// 解析客户端的formData对象 错误对象,普通请求参数 文件上传信息
form.parse(req,(err,fields,files)=>{
// 将客户端传过来的文件地址响应给服务端
res.send(req.cookies)
})
});
app.listen(8080,()=>{
console.log('我监听了8080 http://127.0.0.1:8080')
})
jQuery的ajax使用
<body>
<button type="button" id="button_get">get</button>
<script src="JS/jQuery.js"></script>
<script>
let queryData = {
username: 'kawaii',
age: 20
}
$('#button_get').on('click',function (){
$.ajax({
// 请求方式
type:'get',
// 请求URL
url:'http://localhost:8080',
contentType:'application/json',
// data数据必须为字符串
// 也可以设置 username=kawaii&age=20
data:JSON.stringify(queryData),
// 方法内部自动把JSON字符串转换成JSON对象
success(res){
console.log(res)
},
// 请求失败被调用
error(msg){
console.log(msg)
}
})
})
</script>
</body>