Ajax_$.ajax_模版引擎_FormData_同源政策(jsonp) formData serialize方法
一句话:它是浏览器提供的一套方法,可以实现页面无刷新更新数据,提高用户浏览网站应用的体验
实现步骤:
1. 创建 Ajax 对象
var xhr = new XMLHttpRequest();
2. 告诉 Ajax 请求地址以及请求方式(也可以讲请求参数放入地址内)
xhr.open('get', 'http://www.example.com');
3.发送请求
xhr.send();
4.获取服务器端给与客户端的响应数据
xhr.onload = function () { console.log(xhr.responseText); }
数据格式
http://www.example.com?name=zhang&age=18
一般:服务器端会以 JSON 对象作为响应数据的格式。当客户端拿到响应数据时,要将 JSON 数据和 HTML 字符串进行拼接,然后将拼接的结果展示在页面中。(模版引擎)
数据传输: 在 http 请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输。
所以需要用到
JSON.parse() // 将 json 字符串转换为json对象--一般用在接受响应数据 JSON.stringify() // 将json对象转换为json字符串--一般用在post请求 且数据格式设为json模式时
POST请求
var xhr = new XMLHttpRequest(); //post请求 地址内不能放参数数据 xhr.open('post', 'http://www.example.com'); //设置请求参数的格式 还有application/json格式 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') //post请求将请求参数放入send()方法内 xhr.send('name=zhangsan&age=20'); xhr.onload = function () { console.log(xhr.responseText); }
若是json格式 需将请求参数设置为json字符串JSON.stringify()
get 请求是不能提交 json 对象数据格式的,传统网站的表单提交也是不支持 json 对象数据格式的。
 
低版本 IE 浏览器的缓存问题
问题:在低版本的 IE 浏览器中,Ajax 请求有严重的缓存问题,即在请求地址不发生变化的情况下,只有第一次请求会真正发送到服务器端,后续的请求都会从浏览器的缓存中获取结果。即使服务器端的数据更新了,客户端依然拿到的是缓存中的旧数据。
解决方案:在请求地址的后面加请求参数,保证每一次请求中的请求参数的值不相同
xhr.open('get', 'http://www.example.com?t=' + Math.random());
扩展补充
模版引擎
- 下载 art-template 并引入
 - 准备好模版
 - 说明与哪个数据拼接 template('tpl', {info:data});
 - 
将拼接好的html字符串添加到页面中
 - 
通过模板语法告诉模板引擎,数据和html字符串要如何拼接
 
FormData
FormData对象的作用
1.模拟HTML表单,相当于将HTML表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式
2.异步上传二进制文件
FormData对象的使用
1.准备 HTML 表单 <form id="form">...</form>
2. 将 HTML 表单转化为 formData 对象
var form = document.getElementById('form'); var formData = new FormData(form);
3.提交表单对象
  xhr.send(formData);
注意: // 1.Formdata 对象不能用于 get 请求,因为对象需要被传递到 send 方法中,而 get 请求方式的请求参数只能放在请求地址的后面。
//2.服务器端 bodyParser 模块不能解析 formData 对象表单数据,我们需要使用 formidable 模块进行解析。
FormData 对象的实例方法
1.获取表单对象中属性的值
formData.get('key');
2.设置表单对象中属性的值
 formData.set('key', 'value');
3.删除表单对象中属性的值
 formData.delete('key');
4. 向表单对象中追加属性值
 formData.append('key', 'value');
注意:set 方法与 append 方法的区别是,在属性名已存在的情况下,set 会覆盖已有键名的值,append会保留两个值。
FormData 二进制文件上传
<input type="file" id="file"/>
var file = document.getElementById('file') // 当用户选择文件的时候 file.onchange = function () { // 创建空表单对象 var formData = new FormData(); // 将用户选择的二进制文件追加到表单对象中 因为可以选择多个所以返回一定是个数组 所以this.files[0] formData.append('attrName', this.files[0]); // 配置ajax对象,请求方式必须为post xhr.open('post', 'www.example.com'); xhr.send(formData); }
FormData 文件上传进度展示
文件上传过程中持续触发onprogress事件
// 当用户选择文件的时候 file.onchange = function () { // 文件上传过程中持续触发onprogress事件 xhr.upload.onprogress = function (ev) { // 当前上传文件大小(ev.loaded)/文件总大小(ev.total) 再将结果转换为百分数 // 将结果赋值给进度条的宽度属性 bar.style.width = (ev.loaded / ev.total) * 100 + '%'; } }
FormData 文件上传图片即时预览
图片上传到服务器端以后,服务器端通常都会将图片地址做为响应数据传递到客户端,客户端可以从响应数据中获取图片地址,然后将图片再显示在页面中。
xhr.onload = function () { //将响应的数据转化为json对象 var result = JSON.parse(xhr.responseText); //创建img元素 var img = document.createElement('img'); //将响应的地址数据赋值给预览图片 img.src = result.src; //img元素加载完后添加到boby内 img.onload = function () { document.body.appendChild(this); } }
同源政策
Ajax 只能向自己的服务器发送请求。比如现在有一个A网站、有一个B网站,A网站中的 HTML 文件只能向A网站服务器中发送 Ajax 请求,B网站中的 HTML 文件只能向 B 网站中发送 Ajax 请求,但是 A 网站是不能向 B 网站发送 Ajax请求的,同理,B 网站也不能向 A 网站发送 Ajax请求。
什么是同源
如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于同一个源,其中只要有一个不相同,就是不同源。
https://www.example.com:80/dir/page.html
解决同源政策限制
一.使用 JSONP
jsonp 是 json with padding 的缩写,它不属于 Ajax 请求,但它可以模拟 Ajax 请求。(使用script标签)
1.将不同源的服务器端请求地址写在 script 标签的 src 属性中
2.服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数。
 const data = 'fn({name: "张三", age: "20"})';
 res.send(data);
3.在客户端全局作用域下定义函数 fn
function fn(data){ //需要获取的数据data console.log(data) }
4.在 fn 函数内部对服务器端返回的数据进行处理
JSONP代码优化
- 
客户端需要将函数名称传递到服务器端。
 - 
将 script 请求的发送变成动态请求。
 - 
封装 jsonp 函数,方便请求发送。
 - 
服务器端代码优化之 res.jsonp 方法。
 
//jsonp封装函数 当然jquery已经封装功能更全更强大的jsonp方法和ajax方法 直接使用即可$.ajax() function jsonp (options) { // 动态创建script标签 var script = document.createElement('script'); // 拼接字符串的变量 var params = ''; for (var attr in options.data) { params += '&' + attr + '=' + options.data[attr]; } // myJsonp0124741 var fnName = 'myJsonp' + Math.random().toString().replace('.', ''); // 它已经不是一个全局函数了 // 我们要想办法将它变成全局函数 window[fnName] = options.success; // 为script标签添加src属性 script.src = options.url + '?callback=' + fnName + params; // 将script标签追加到页面中 document.body.appendChild(script); // 为script标签添加onload事件 script.onload = function () { document.body.removeChild(script); } }
二.CORS 跨域资源共享
CORS:全称为 Cross-origin resource sharing,即跨域资源共享,它允许浏览器向跨域服务器发送 Ajax 请求,克服了 Ajax 只能同源使用的限制。
Node 服务器端设置响应头:
app.use((req, res, next) => { //允许访问的地址域 *代表所有 也可指定地址域 如:Access-Control-Allow-Origin: 'http://localhost:3000' res.header('Access-Control-Allow-Origin', '*'); //设置允许访问的请求方式 'GET', 'POST' 或者两者都可 res.header('Access-Control-Allow-Methods', 'GET, POST'); next(); })
三 服务器端之间访问
同源政策是浏览器给予Ajax技术的限制,服务器端是不存在同源政策限制
可以服务器之间先访问 需要在服务器端用到require('request')模块
得到的数据 再通过ajax发送给客服端
cookie与跨域请求
在使用Ajax技术发送跨域请求时,默认情况下不会在请求中携带cookie信息。
withCredentials属性:
指定在涉及到跨域请求时,是否携带cookie信息,默认值为false
Access-Control-Allow-Credentials:true 允许客户端发送请求时携带cookie
比如实现跨域登陆: 在网站A中客户端发起请求
loginBtn.onclick = function () { // 将html表单转换为formData表单对象 var formData = new FormData(loginForm); // 创建ajax对象 var xhr = new XMLHttpRequest(); // 对ajax对象进行配置 xhr.open('post', 'http://localhost:3001/login'); // 当发送跨域请求时,设置携带cookie信息(重点) xhr.withCredentials = true; // 发送请求并传递请求参数 xhr.send(formData); // 监听服务器端给予的响应内容 xhr.onload = function () { console.log(xhr.responseText); } }
B网站服务端:
// 拦截所有请求 app.use((req, res, next) => { // 1.允许哪些客户端访问我 // * 代表允许所有的客户端访问我 // 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息 res.header('Access-Control-Allow-Origin', 'http://localhost:3000') // 2.允许客户端使用哪些请求方法访问我 res.header('Access-Control-Allow-Methods', 'get,post') // 允许客户端发送跨域请求时携带cookie信息 res.header('Access-Control-Allow-Credentials', true); next(); });
jQuery 中的 Ajax
作用:发送Ajax请求。
$.ajax({ type: 'get', url: 'http://www.example.com', data: { name: 'zhangsan', age: '20' }, //若是get请求可以省去 contentType属性 contentType: 'application/x-www-form-urlencoded', //请求发送前执行 beforeSend: function () { return false }, success: function (response) {}, error: function (xhr) {} });
作用:发送jsonp请求
$.ajax({ url: 'http://www.example.com', // 指定当前发送jsonp请求 dataType: 'jsonp', // 修改callback参数名称 可省略 jsonp: 'cb', // 指定函数名称 可省略 jsonCallback: 'fnName', success: function (response) {} })
$.get()、$.post()
作用:$.get方法用于发送get请求,$.post方法用于发送post请求
$.get('http://www.example.com', {name: 'zhangsan', age: 30}, function (response) {}) 
$.post('http://www.example.com', {name: 'lisi', age: 22}, function (response) {})
serialize方法:
formData可以拼接表单参数  但 formData为H5 有兼容性
serializa()方法 可以拼接 但只能拼接 没有其他功能 可以自己利用serializaArry() 方法封装一个转化为对象的函数
将表单中的数据自动拼接成字符串类型的参数
var params = $('#form').serialize(); // params为 name=zhangsan&age=30
全局事件
只要页面中有Ajax请求被发送,对应的全局事件就会被触发
.ajaxStart() // 当请求开始发送时触发
.ajaxComplete() // 当请求完成时触发
//当页面有ajax请求发送时触发 $(document).on('ajaxStart', function () {
NProgress.start()
) //当页面有ajax请求完成时触发
$(document).on('ajaxComplate', function () {
NProgress.done()
)
NProgress 纳米级进度条
使用: 引入 相关的 css文件 与 js文件
2 在代码开始写入
<script>NProgress.start()</script>
和在代码结尾处
<script>NProgress.done()</script>
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
location.href= 'index.html' //跳转地址 location.reload() //刷新当前页面 llocation.search() //获取到当前地址参数 类似 ?name=zhangsan&age=18 //自己封装一个获取地址栏内的指定参数 没有则返回 -1 function getUrlParams(name) { var paramsAry = location.search.substr(1).split('&'); // 循环数据 for (var i = 0; i < paramsAry.length; i++) { var tmp = paramsAry[i].split('='); if (tmp[0] == name) { return tmp[1]; } } return -1; }
                    
                
                
            
        
浙公网安备 33010602011771号