WEB第八天
一、Ajax异步请求
Ajax是JS异步请求的全称, 包含请求对象XMLHttpRequest、FormData及请求资源与数据解析等一系列操作。Ajax主要使用场景是不阻塞当前的文档(页面),以异步方式去加载或读取阻塞性的资源,如网络请求、加载文件等。
ajax请求的流程
1. 创建XMLHttpRequest对象
let req = new XMLHttpRequest()
2. 打开请求, 指定请求方法 method、请求接口 url, 是否异步的boolean值
req.open(method: 'get|post',
url: 'http://10.36.174.6:5000/fanyi',
async: true)
3. 设置请求头
// 常用的请求头的key: Content-Type/Host/Referer/Cookie/Content-length
req.setRequestHeader(key, value)
4. 请求响应的监听函数
req.onload = function(){
// 响应成功
// 判断响应状态码 200, req.status
// 判断响应的数据可以读取 req.readyStatus == 4
// 读取响应的数据 req.responseText
}
5. 准备的请求参数(查询参数, 表单参数)
查询参数 -> 请求方法是GET, 查询参数与url拼接在一起的, ?a=123&b=789
表单参数 -> 请求方法是POST, 用FormData对象封装表单参数
form_data = new FormData()
form_data.append('name', value) // value可以是常用的数据类型值, 也可以文件对象
6. 发送请求,可带请求数据
req.send()
req.send(form_data)
req.send('a=123&b=789')
req.send('{"name":"disen", "pwd": "123"}') // content-type: application/json
5.1 案例分析-百度翻译
请求接口(url): https://fanyi.baidu.com/v2transapi
请求方法: POST
请求参数(表单):
from: en
to: zh
query: apply
simple_means_flag: 3
sign: 240425.477208
token: 9fc86fc625f77e503a53653963384464
响应的数据:
{
"trans_result": {
"data": [
{
"dst": "应用",
"prefixWrap": 0,
"result": [
[
0,
"应用",
[
"0|5"
],
[],
[
"0|5"
],
[
"0|6"
]
]
],
"src": "apply"
}
],
"from": "en",
"status": 0,
"to": "zh",
"type": 2,
"phonetic": [
{
"src_str": "应",
"trg_str": "yìng"
},
{
"src_str": "用",
"trg_str": "yòng"
}
]
},
...
Ajax请求实现
<!--
oninput 当输入新的内容时调用的事件监听函数
onchange 当输入内容后,回车或失去焦点时调用的事件监听函数
-->
<input name="keyword" onchange="fanyi(this.value)">
<div id="result"></div>
function fanyi(word) {
// 1. 创建XHR对象
var request = new XMLHttpRequest();
// 2. 设置打开接口及方法
// request.open(method, url, async, user, password)
// 'https://fanyi.baidu.com/v2transapi'
request.open('post','http://localhost:5000/fanyi', true);
// 3. 根据需要设置请求头信息
request.setRequestHeader('Referer', 'https://fanyi.baidu.com/');
request.setRequestHeader('Cookie','BAIDUID=C54A17B138600A57FB71E5003D727C91')
// 4. 设置响应的监听
request.onload = function () {
// 请求有响应信号
console.log(request.statusText, request.status);
// 判断请求是否成功
// 判断是否可读响应数据
if(request.status == 200 && request.readyState == 4){
// 解析数据
let respData = request.responseText
console.log(respData)
console.log(typeof respData)
respData = JSON.parse(respData) // 将文本数据转成json对象
// DOM操作
document.getElementById('result').innerText = respData.result;
}
};
// 5. 生成请求数据对象-form表单参数
// FormData默认的Content-Type: multipart/form-data
let form_data = new FormData();
form_data.append('from', 'en');
form_data.append('to', 'zh');
form_data.append('query', word);
form_data.append('simple_means_flag', 3);
form_data.append('sign', '240425.477208');
form_data.append('token', '9fc86fc625f77e503a53653963384464');
// 6. 发起请求
request.send(form_data)
}
说明: 百度翻译的接口没有处理跨域问题,所有访问是自己写的服务器
【扩展】基于Flask+Flask-Cors实现跨域请求的API接口
#!/usr/bin/python3
# coding: utf-8
from flask import Flask
from flask import request, jsonify
from flask_cors import CORS
api_server = Flask(__name__)
stores ={
'apply': '应用',
'apple': '苹果',
'css': '样式'
}
@api_server.route('/fanyi', methods=['POST'])
def fanyi():
key = request.form.get('query')
return jsonify({
'query': key,
'result': stores.get(key, '查无此单词')
})
if __name__ == '__main__':
print('正在启动api服务')
CORS().init_app(api_server)
api_server.run(host='0.0.0.0')
要求安装 flask库和flask-cors库
(venv) > pip install flask flask-cors
5.2 案例分析–用户登录
服务端api接口实现代码
@api_server.route('/login', methods=['POST'])
def login():
data = request.get_json()
if data.get('name') == 'disen' and data.get('pwd') == "888":
msg = '登录成功'
else:
msg = '用户名或口令出错'
return jsonify(locals())
前端ajax请求
function login(info) {
let request = new XMLHttpRequest()
request.open('post', 'http://localhost:5000/login',true);
request.setRequestHeader('Content-Type', 'application/json')
request.onload = function () {
console.log(request.responseText)
};
request.send(JSON.stringify(info));
}
由于后端api接口描述的是post请求,且要求上传json数据,所以在前端发起请求时,必须设置请求头Content-Type表示上传的数据是json格式数据。
另外,js中提供一个更高级的AJAX请求方法, fetch()函数,替换较早的XMLHttpRequest。
fetch API详细用地参考: https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
可以将上面的请求改成fetch()实现
<form>
用户名: <input name="name"> <br>
口令: <input name="pwd"><br>
</form>
<button onclick="loginFetch()">登录</button>
function loginFetch() {
let user_info = {
name: document.forms[0].name.value,
pwd: document.forms[0].pwd.value
}
fetch('http://10.36.174.6:5000/login', {
body: JSON.stringify(user_info),
method: 'post',
headers: {
'Content-Type': 'application/json'
}
}).then(response => response.json())
.then(data => {
alert(data.msg);
console.log(data);
})
.catch(error=>{
console.error(error)
})
}
get 请求
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
post请求
// Example POST method implementation:
postData('http://example.com/answer', {answer: 42})
.then(data => console.log(data)) // JSON from `response.json()` call
.catch(error => console.error(error))
function postData(url, data) {
// Default options are marked with *
return fetch(url, {
body: JSON.stringify(data), // must match 'Content-Type' header
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
})
.then(response => response.json()) // parses response to JSON
}
POST JSON数据
var url = 'https://example.com/profile';
var data = {username: 'example'};
fetch(url, {
method: 'POST', // or 'PUT'
body: JSON.stringify(data), // data can be `string` or {object}!
headers: new Headers({
'Content-Type': 'application/json'
})
}).then(res => res.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
上传文件
var formData = new FormData();
var fileField = document.querySelector("input[type='file']");
formData.append('username', 'abc123');
formData.append('avatar', fileField.files[0]);
fetch('https://example.com/profile/avatar', {
method: 'PUT',
body: formData
})
.then(response => response.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
二、jQuery
jQuery是javascript轻量级框架, 可以查询元素、动态操作DOM、事件绑定与解绑、动画、CSS的处理及Ajax异步请求。jQuery也包含一部分UI插件,基于jQuery框架。
2.1 jQuery对象与Element对象
<input name="num">
<div id="result"></div>
-
jQuery对象
// $(':input') 创建了jQuery对象,等同于 jQuery(':input') let inputObj = $(':input') // 查找页面document中所有input标签元素
-
从jQuery对象中提取Element对象
let input_e = inputObj[0] // jQuery对象可以看成是一个数组, 从jQuery对象中提取第一个input标签 // Element对象使用它自己的属性或方法 input_e.value += 'disen'
-
将Element对象转成jQuery对象
// 将element标签对象转成jQuery对象之后,调用jQuery对象的函数添加class属性 $(input_e).addClass('warn')
2.2 选择器与常用函数
2.2.1 常用的选择器
常用的选择有: id选择器、class选择器、标签选择器、属性选择器、表单选择器等
<input class="error" name="phone">
<p id="result"></p>
$('#result') // id选择器
$('.error') // class类选择器
$('p') // 标签选择器
$('[name="phone"]') // 属性选择器
$(':text') // 表单选择器
2.2.2 常用函数
jQuery对象的常用的函数较多,请查询API文档。
let jqObj = $('p');
jqObj.addClass('info') // 增加样式
jqObj.attr('class', 'info') // 设置class的属性值为info
jqObj.attr('css') // 返回class属性的值
jqObj.html('新的内容')
jqObj.html() // 返回p标签中的文本内容
作业:
- 练习jQuery的选择器
- 练习jQuery的核心函数
- 尝试jQuery的ajax的函数
- $.ajax()
- $.getJSON()