2020蓝旭工作室暑期前端培训课Day3——前后端交互的实现、js异步机制、前端模块化开发

HTTP基础

HTTP简介

HTTP协议(HyperText Transfer Protocol)全称超文本传输协议,是因特网上最广泛的一种网络传输协议,基于TCP/IP协议传输数据。

HTTP三个特点

  • 它是无连接的
  • 它是媒体独立的
  • 它是无状态的

HTTP工作原理

HTTP基于客户端服务端模式,一次HTTP事务处理过程如下:
Step1:客户端与服务端建立连接
Step2:客户端向服务端发出请求
Step3:服务端接受请求,并根据请求返回响应的数据信息作为响应
Step4:客户端接受服务端响应
Step5:客户端与服务端关闭连接

HTTP请求

HTTP请求报文包含如下内容:

  • 请求的方法:常见两种GET、POST
  • 请求的URL
  • 请求的包头:Request Header,以键值对形式存在,告知服务器有关客户端请求的信息,例如Cookie
  • 请求的包体:Request Body,用于POST方法,包含向服务器发送的数据,以及包体类型和包体长度
  • Content-Type:Content-Type,即内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件。Content-Type属性指定响应的 HTTP内容类型。如果未指定 Content-Type,默认为text/html。
    常见Content-Type:
    • text/html : HTML格式
    • text/plain :纯文本格式
    • application/x-www-form-urlencoded:表单默认提交格式,form表单数据被编码为key/value格式发送到服务器
    • application/json 参数为json格式
    • multipart/form-data 上传文件用这种格式

2020蓝旭工作室暑期前端培训课Day3——前后端交互的实现、js异步机制、前端模块化开发_第1张图片

HTTP响应

HTTP响应报文包含以下内容

  • 状态行:包含HTTP协议版本字段、状态码、状态码文本描述
  • 响应头:包含了
  • 响应体:包含服务器返回给客户端的文本信息
    2020蓝旭工作室暑期前端培训课Day3——前后端交互的实现、js异步机制、前端模块化开发_第2张图片

状态码

状态码 描述
100~199 信息,服务器收到请求,需要请求者继续执行操作
200~299 成功,操作被成功接收并处理
300~399 重定向,需要进一步的操作以完成请求
400~499 客户端错误,请求包含语法错误或无法完成请求
500~599 服务器错误,服务器在处理请求的过程中发生了错误

常见状态码:

  • 200 OK:表示客户端请求成功
  • 400 Bad Request:表示客户端请求有语法错误,不能被服务端解析
  • 403 Forbidden:服务器接收到请求,但拒绝提供服务
  • 404 Not Found:请求资源不存在
  • 500 Internet Server Error:服务端发生错误,无法处理请求
  • 503 Service Unavailable:服务器暂时无法处理请求

JSON

JSON简介

  • JSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式。
  • JSON是JavaScript的原生内容,JavaScript可以十分方便的解析JSON,因此在Web开发中,JSON使用的频率要远高于XML
  • JSON格式
    JSON有两种结构组成:Object, Array,包含四种基本数据类型:Number,String,boolean,null
    下面是一串JSON文本的示例:
{
     
    "id":100,
    "username":"BH13",
    "age":21,
    "sex":"male",
    "isLogin":true,
    "girlfriend":null,
    "ex-girlfriend":[
        {
     
            "name":"Ada",
            "age":20
        },
        {
     
            "name":"Bella",
            "age":18
        },
        {
     
            "name":"Cherry",
            "age":30
        }
    ],
    "什么情况":"你变成方块字啦"
}

JavaScript中的JSON

JavaScript有一个内置对象JSON,用于处理JSON数据

  • JSON.stringify(object) 用于将数据转化为JSON字符串
  • JSON.parse(string) 用于将JSON字符串转化为JSON对象
var json = {
     
    name:'BH13',
    age:20,
    中文名:'不便透露'
}

var jsonstr = JSON.stringify(json);
var jsonobj = JSON.parse(jsonstr);
console.log(jsonstr); 
console.log(jsonobj);

运行结果:
运行结果

前后端交互数据方式

cookie

客户端将数据存储在cookie中,cookie会放在请求头中随着HTTP请求发送给服务端,由服务端解析数据。同样服务端可以产生cookie,发送给客户端,客户端接收到cookie后保存在本地

表单提交

传统的jsp,php等服务端语言,在页面内设置form表单,确定需要传递的参数,通过submit传输到服务器
下面是一个通过form表单访问快递鸟打印接口的例子:

<form id="form1"
	  action="http://www.kdniao.com/External/PrintOrder.aspx"
	  method="post"
	  target="_self">
    <div>
        <input type="text" id="RequestData" name="RequestData">请求数据
    div>
    <div>
        <input type="text" id="DataSign" name="DataSign"/>签名
    div>
    <div>
        <input type="text" id="EBusinessID" name="EBusinessID"/>商户id
    div>
    <div>
        <input type="text" id="IsPreview" name="IsPreview" value="1"/>
        <span style="color: red;">是否预览 0-不预览 1-预览span>
    div>
    <div>
        <input type="submit" value="打印" />
    div>
form>

AJAX

下一节会进行详解

JSONP

  • 一种非官方跨域数据交互协议
  • 利用具有src属性标签不受跨域限制的特性
  • 通过动态创建script标签来从服务器端引入js代码,从而获得服务器传来的数据

js实现:

//指定的回调函数
function getData(data){
     
	console.log(data)
}

//动态创建script标签
function addScript(){
     
	var url = 'http://localhost:9000/server.js?callback=getData';
	var script = document.createElement('script');
	script.src = url;
	var body = document.getElementsByTagName('body')[0];
	body.appendChild(script);
}

jQuery实现:

$.ajax({
     
	type:'get',   //强制把get改为post,最后发现还是get
	url:'http://localhost:9000/server.js',
	dataType:'jsonp',
	jsonp: "callback",  //指定路径里的参数名
    jsonpCallback:"getData", //指定回调函数名
	success: function(data){
     
	    console.log(data);
	},
	error: function(){
     
		console.log('请求出错')
	}
})

JSONP弊端:

  • 服务器需要改动代码,如果调用的服务器接口不是自己的,就无能为力
  • 只能用get方法
  • 发送实质上并不是xhr

WebSocket

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

AJAX技术

AJAX简介

  • AJAX(Asynchronous JavaScript and XML)指异步的JavaScript和XML,它一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。这种异步交互的方式,使用户单击后,不必刷新页面也能获取新数据。使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。
  • 异步和同步:异步是一个线程在执行中,下一个线程不必等待它执行完就可以开始执行,同步是指一个线程要等待上一个线程执行完才能开始执行,同步可以看做是一个单线程操作,只要客户端请求了,在服务器没有反馈信息之前是一个线程阻塞状态。
  • XML是一种数据交换语言,但是因为XML解析较为困难的原因,现在Web开发中流行JSON

AJAX原理

AJAX相当于是在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给 Ajax引擎自己来做, 只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。

2020蓝旭工作室暑期前端培训课Day3——前后端交互的实现、js异步机制、前端模块化开发_第3张图片

使用AJAX

  • 原生js

创建AJAX对象

var xhr = new ActiveXObject('Microsoft.XMLHTTP');  //ie6以下
var xhr = new XMLHttpRequest();

使用AJAX对象的方法

xhr.open(method,url,async, username, password)  //设置请求基本信息
xhr.setRequestHeader(header, value)  //设置请求头
xhr.onreadystatechange()   //监听readyState属性
xhr.getResponseHeader()   //获得响应头
xhr.ontimeout() //请求超时后的回调函数
xhr.send()  //发送请求

使用AJAX对象的属性

xhr.readyState:获得请求的状态
xhr.status:获得HTTP响应的状态码
xhr.responseText:获得服务器返回的文本数据
xhr.responseXML:获得服务器返回的一个XML数据
xhr.timeout:设置请求的超时时间(ms)

readyState取值:

readyState 描述
0 请求未初始化
1 服务器连接已建立
2 请求已接收
3 请求处理中
4 请求已完成,且响应已就绪

一段完整的使用AJAX的实例:

function requestServer(sendData){
     
	var xhr;
    if (window.XMLHttpRequest)
    {
     
        //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
        xhr = new XMLHttpRequest();
    }
    else
    {
     
        // IE6, IE5 浏览器执行代码
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }

    //开启xhr请求,下面的url是博主的一个测试地址
    xhr.open('post', 'http://localhost:9000/server.js', true);
    
    //设置超时时间为10s
    xhr.timeout = 10000;

    //设置请求头的content-type
    xhr.setRequestHeader('content-type', 'application/json;charset-UTF-8');

    //监听readyState的变化
    xhr.onreadystatechange = function(){
     
        if(xhr.readyState == 4 && xhr.status == 200){
     
        	// 请求成功的后续处理写在下面
            console.log('request success');
            if(xhr.responseText){
     
                console.log(JSON.parse(xhr.responseText));   //接收后端传过来的数据
            }
            else{
     
                console.log(xhr.responseXML); //接收后端传来的XML格式的数据
            }
        }
    }

    //超时后调用的函数
    xhr.ontimeout = function(e){
     
        console.log('request timeout');
    }

    //发送数据
    xhr.send(JSON.stringify(sendData))
}
  • jQuery中的AJAX

    jQuery对AJAX做了较为完善的封装
    最底层:$.ajax()
    第二层:$.load(), $.get(), $.post()
    第三层:$.getScript(), $.getJSON()

$.ajax({
     
    url:'http://localhost:9000/server.js', //请求地址
    headers:{
        
        'token':token,
    },  //设置请求头
    type:'post', //请求方法
    timeout:10000, //请求的超时时间
    data:JSON.stringify(sendData), //发送给服务端的数据
    dataType:'json', //预期服务器返回的数据
    contentType:'application/json;charset-UTF-8', //设置请求头中的contentType
    complete:function(xhr, textStatus){
     
        console.log(xhr, textStatus)
    },//请求完成的回调函数
    success:function(data, textStatus){
       
        console.log(data, textStatus); //data即为服务器返回的数据
    },  //请求成功并且服务器响应成功的回调函数
    error:function(xhr, textStatus, errorThrown){
     
        console.log(xhr,textStatus, errorThrown);
    } //请求失败时的回调函数
})

跨域问题

怎样叫做跨域

一个域名地址如下:
http://www.billhao.com:8080/web/index.html
协议,主域名,子域名,端口号(默认80端口),任意一个不相同时,都叫跨域

同源策略

同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出请求后服务端发回的数据,即请求发送了,服务器响应了,但是无法被浏览器接收。
同源策略会造成:
cookie、localStorage和IndexDB无法读取
DOM无法获得
AJAX请求不能发送

注:所谓同源是指,域名,协议,端口相同。

解决跨域问题

  1. 浏览器设置
  2. 反向代理(Nginx)
  3. JSON with Padding(JSONP)非官方协定
  4. Cross-Origin Resource Sharing(CORS)跨域资源共享

JavaScript异步机制

JavaScript单线程

单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。JavaScript作为浏览器脚本语言决定了他必须是单线程执行,否则会造成某些处理产生冲突。

JavaScript中的异步机制

对于客户端页面来说,如果所有的操作都是单线程同步的,极易造成页面的阻塞,因此,异步机制是必须的。JavaScript是单线程,它是同步执行的是无可争议的,但是浏览器内核是异步的,通过浏览器内核的异步调度处理,JavaScript有自己实现异步的方法,即事件循环(event loop):
1.所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)
2.主线程之外,还存在一个任务队列(task queue),只要异步任务有了运行结果,就在“任务队列”之中放置一个事件,不同的异步操作添加到任务队列的时机也不同
3.一旦“执行栈”中的所有同步任务执行完毕,系统就会读取“任务队列”,看看里面有哪些事件。那些对应的异步任务,就结束等待状态,进入执行栈开始被执行。
4.循环执行 上述三步

2020蓝旭工作室暑期前端培训课Day3——前后端交互的实现、js异步机制、前端模块化开发_第4张图片

一个经典实例:

console.log(1);
setTimeout(function(){
     
    console.log(2);
}, 0);
console.log(3);

//执行结果1, 3, 2

异步加载JavaScript

  • 给script标签加defer属性

    这是IE浏览器独有的方法,这种方法也可以直接在script标签里写入代码

  • 给script标签加aysnc属性

    这个方法无法在script标签里写入js代码

  • 动态加载script标签

function addScript(){
     
    var script = document.createElement('script');
    script.type = "text/javascript";
    script.src = "demo.js";
    docuemnt.head.appendChild(script);
}

前端模块化开发

概念

所谓模块化开发,是指将一个项目按照功能划分,理论上一个功能一个模块,互不影响,在需要的时候载入,尽量遵循高内聚低耦合

模块化编程写法

  • 函数式写法
function fun1(){
     }
function fun2(){
     }

缺陷:所有模块都暴露在全局对象中。

  • 对象写法
var mod = {
     
    __cnt__ = 0,
    fun1:function(){
     },
    fun2:function(){
     }
}

缺陷:mod内的变量可以直接通过mod.__cnt__访问到:

  • 立即执行函数写法
var mod = (function(){
     
    var __cnt__ = 0;
    var fun1 = function(){
     };
    var fun2 = function(){
     };
    return {
     
        fun1:fun1,
        fun2:fun2
    };
})

这样写就避免了__cnt__在外部被访问

  • 放大模式

下面的代码实现了为mod扩展了一个模块

var mod = (function(){
     
    var __cnt__ = 0;
    var fun1 = function(){
     };
    return {
     
        fun1:fun1
    };
})()

mod = (function(m){
     
    m.fun2 = function(){
     };
    return m;
})(mod)
  • 输入全局变量
    为一个模块引入一些全局变量供模块使用,例如将一些js库定义的全局变量导入

    var mod = (function($, cptable){
           })(jQuery, cptable);
    

使用模块

  • 传统的引入多个模块方式

    <script src="a.js">script>
    <script src="b.js">script>
    <script src="c.js">script>
    

    缺陷:增加了页面加载脚本文件的压力,对于耦合性高的不同模块之间,需要有严格的执行顺序,而且易造成变量冲突。

  • AMD规范
    AMD(Asynchronous Module Definition)采用异步加载模块,模块的加载不影响后面语句的运行,所有依赖此模块的语句,都定义在一个回调函数中,当模块加载完成,执行回调函数。
    实现语法:

    require(module, callback)
    
  • RequireJS
    RequireJS是一个实现了AMD规范的js模块加载库,它有以下优势:

  1. 异步加载:RequireJS是异步加载模块,模块加载完毕执行回调函数,避免了页面的阻塞

  2. 按需加载:当需要某个模块时,他才会去加载

  3. 依赖管理:RequireJS的机制保证了加载完所有依赖模块后才会去执行相关逻辑

  4. 版本管理:只需更改引入模块处的地址信息就可以控制模块版本的更换
    使用RequireJS只需在页面中引入require.js,然后再引入main.js,接着再对main.js进行配置

    require.config({
           
        paths:{
           
            "jquery":'../lib/jquery.min'
        }//配置引入模块的路径
    });
    require(['jquery'],function($){
           
        //在此写jQuery代码
    })//第一个参数是引入模块的列表,第二个参数是回调函数
    

CommonJS规范

CommonJS是适用于服务端开发的一个模块规范,它是同步加载模块,Node.js的模块系统参照CommonJS规范定制,并不适用于浏览器开发。

ES6的模块化开发

  • export的使用
//mod1.js:导出default模块
export default function(){
     };
//mod2.js:直接导出模块
export function mod(){
     };
//mod3.js:统一导出模块
var num = 1;
var arr = [1,2,3];
var obj = {
     name:'BH13',age:20};
function mod3(){
     }

export {
     num, arr, obj, mod3}
  • import的使用
import mod1 from 'mod1.js' //导入由export default导出的模块
import {
     mod as mod2} from 'mod2.js'  //将导入的模块名称重新命名
import {
     num, arr, obj, mod3} from 'mod3.js'  //导入指定了名称的模块

模块化开发详细内容可以看一看这个博客:
阮一峰的网络日志:Javascript模块化编程(一):模块的写法

你可能感兴趣的:(javascript,jquery,http,web,前端)