封装Ajax和跨域
目录
- 引言
- 封装ajax
- 案例:使用自封装ajax
- 案例:动态加载瀑布流
- 跨域
- 引言
对于Ajax现在相信大家已经不会陌生了,无论是原生的XMLHttpRequest方式发送还是通过jQuery框架中提供的$.ajax方式。但是从实际工作角度来说并不是所有的公司都喜欢采用上面两种方式进行请求的发送。
其原因在于:
(1)原生的方式过于繁琐,并且大量重复代码。
(2)jQuery的方式虽然方便,但必须引入jQuery框架,
而框架中不是所有的内容都能用到,这就造成了大量无用代码的堆积。占用资源
因此我们自行封装满足于我们需求的Ajax框架就势在必行,这节课我们就一起来封装一个属于我们自己的Ajax框架。
在此之前为了能更好的的理解今天的内容,让我们先一起复习一下前两种方式:
(1)原生Ajax请求
(2)jQuery中的$.ajax()请求
1)原生ajax请求
var xhr = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("");
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
console.log(JSON.parse(xhr.responseText));
}else{
console.log(xhr.statusText);
}
}
}
xhr.open('请求类型get/post','请求地址url',true);
xhr.setRequestHeader('Content-Type','application/json');
xhr.send(如果post请求则在这些formData);
2), jQuery中的$,ajax()请求
<script src='xxx/jquery1.12.3.min.js'></script>
<script>
//…
$.ajax({
type:'get|post',
url:'http://xxxx/xxx.php',
dataType:'json',
data:'如果是post请求则必须写',
success:function(jsonData){
console.log(jsonData);
},
error:function(err){
console.log(err);
}
});
</script>
好了,让我们暂且先复习到这里。如果你对上面的内容能够掌握的非常熟练的话,就能够在我们刚才书写的过程中感到一丝丝的不舒服的地方。
那就是jq的方式简便快捷又好用,相比之下原生的写法简直麻烦。
而这,正是我们要自行封装Ajax的原因:
因为jq的方式简便快捷,但是jq框架却过于庞大。
所以我们要自行编写一个属于我们自己的,只用于处理Ajax的简便框架。
2,封装ajax
实际上自封装Ajax请求文件,就是将原生Ajax的请求步骤抽象为一个函数,并单独生成一个js文件保存,当用到的时候直接引入这个文件的过程。
很显然这是个一次性的工作,封装完毕之后我们以后直接拿来直接使用即可。
封装Ajax大致分成下列几个步骤:
(1)提供创建xhr对象的兼容性函数。
(2)提供发送请求的对外接口
(3)设计并约定对外接口的参数规格
(4)实现对外接口中参数处理
(5)实现对外接口中响应处理
(6)实现对外接口中发送处理
(7)设置命名空间,避免全局变量污染。
(1)提供创建xhr对象的兼容性函数
a.让我们先创建一个js文件,并命名为EncapsulationAjax.js。(这就是我们的框架文件)
b.在这个文件内部先声明一个无参函数,命名为createXhr。
function createXhr(){}
c.这个函数是为了获得xhr兼容性对象才书写的,因此在里面书写兼容性代码
function createXhr(){
return window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject(‘’);
}
(2)提供发送请求的对外接口
a.声明对外发送请求的接口,命名为ajax。
function ajax(){}
b.为接口设置一个json格式的参数用于接收相关数据,命名为jsonObj
function ajax(jsonObj){}
(3).设计并约定接口的参数规格
(4)实现对外接口中参数处理
a.对外接口中创建xhr对象
function ajax(jsonObj){
var xhr = createXhr();
}
b.根据请求方式设置参数。
function ajax(jsonObj){
var xhr = createXhr();
}
(5)实现对外接口中响应处理
a.根据请求方式设置回调函数。
function ajax(jsonObj){
//…
if(jsonObj.async === true){
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
if(xhr.status == 200){
jsonObj.success(JSON.parse(xhr.responseText));
}else{
jsonObj.error(xhr.statusText);
}
}
}
}
}
(6)实现对外接口中发送处理
a. 调用open+send函数。
function ajax(jsonObj){
//…
xhr.open(obj.method,obj.url,obj.async);
if(obj.method === "post"){
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(obj.data);
}else{
xhr.send();
}
}
(7)设置命名空间,避免全局变量污染
因为我们所编写的js文件中存在大量全局变量,而这样的全局变量会对其他文件中的内容造成不可预估的影响。在js中函数可以划分作用域,因此我们采用自执行函数将整体包裹,避免了内部创建的变量对全局变量造成的影响。
但是这样一来带来的一个重要问题就是,内部创建的函数对外也变成了不可见状态,因此我们可以借助window对象来将内部创建的对外接口设置为“可见状态”.
(function(){
//…
funtion ajax(){
//…
}
window.ajax = ajax;
}());
OK,到此为止一个名为EncapsulationAjax的框架封装完成了。
这个框架归属于我们自己,并且具有我们所期待的一系列特点:
a.轻量级,寥寥几十行代码
b.兼容性,能够处理IE中很多版本的Ajax请求
c.便捷性,参数都是自己规定的,用着方便
d.扩展性,如果还需要更多的功能直接添加进去即可,不会有任何内容冲突。
那么既然已经编写了一个属于我们自己的工具,就让我们来看看在实际工作中他的表现吧!
3,案例:使用自封装ajax
要求:
(1) html文档结构如下:
(2)发送Ajax使用EncapsulationAjax.js提供的方法实现。
(3)php文档内容如下:
if($_POST){
echo json_encode(array('info'=>$_POST, 'desc'=>'post'));
}else{
echo json_encode(array('info'=>$_GET, 'desc'=>'get'));
}
Post请求返回结果:
Get请求返回结果
4,案例:动态加载瀑布流
要求:
(1)整体html结构和js部分都和之前的代码没有冲突和区别
只是需要将【原本的模拟数据】变成【真正的Ajax请求来的数据】。
(2)对于获取数据而言,采用get请求。
(3)最后需要将整个处理瀑布流加载过程的代码,放置到success中执行
(4)php后台文件中只需要将图片的路径地址构建,并返回即可。
$imgArr = [‘http://127.0.0.1/waterfall/i1.jpg’,‘http://127.0.0.1/waterfall/i2.jpg’,…];
$finalArr = array('desc'=>'success', 'imgArr'=>$imgArr);
echo json_encode($finalArr);
ajax({
method:'get',
url:'waterfall.php',
async:true,
success:function(data){
//…构建瀑布流的代码
},
error:function(error){
console.log(error);
}
});
5.跨域
(1)浏览器同源政策
(2)Ajax跨域
(3)JSONP跨域方案(get请求)
(1).浏览器同源政策
(1)浏览器同源政策
起源:1995年,同源政策由Netscape公司引入浏览器。
含义:最初的目的是某页面所设置的cookie,只能由其“同源”页面打开。
说明:“同源”:协议相同、域名相同、端口相同
例子:http://www.frank.com/sxt/page.html这个网址
协议是:http://
域名是:www.frank.com
端口是:80(默认端口可以省略)。
它的同源情况如下:
http://www.frank.com/sxt2/other.html:同源
http://frank.com/sxt/other.html:不同源(域名不同)
http://v3.www.frank.com/sxt/other.html:不同源(域名不同)
http://www.frank.com:81/dir/other.html:不同源(端口不同)
目的:同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
限制:随着互联网的发展,"同源政策"越来越严格。
目前,如果非同源,共有三种行为受到限制:
(1)Cookie、LocalStorage 和 IndexDB 无法读取。
(2)DOM 无法获得。
(3)AJAX 请求不能发送。
补充:凡事都有利有弊,尽管限制是有必要的,
但在有些情况下合理的用途也会因“同源政策”而受到影响。
因此我们将要为大家介绍的一些规避上述限制的手段,就是【跨域】的由来。
(2)Ajax跨域
描述:Ajax跨域指的是将Ajax请求进行跨域处理,而不是说在Ajax中提供了跨域的方法。
由来:同源政策中明确规定Ajax请求只能发给同源的网址,否则就会发生跨域报错。
解法:除了设置代理之外页面中有三种常见的解决跨域的手段,
而根据我们所掌握的内容来考虑,我们只学习最常见的一种叫做JSONP的方法。
其余另外两种分别叫做webSocket和CORS。
(3)JSONP跨域方式
描述:JSONP是服务器与客户端跨源通信的最常用方法。
最大特点就是简单适用,老式浏览器全部支持,对服务器改造非常小。
本质:实际上利用了script标签引入js文件,并解析执行的原理。
语法:
(1)在html中插入script标签,并利用script标签发起跨源请求
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = '跨源url地址?【前后端约定回调关键词】=【回调函数名】';
document.body.appendChild(script);
(2)在服务器对应php文件中通过拼接字符串,模拟函数调用。
并将要返回数据通过回调函数参数返回。
$response = $_GET['前后端约定回调关键词'];
echo $response."(".json_encode(要返回数据).")";
(3)在html页面中,显式写出回调函数。这样当跨源请求完成后对应回调函数会自动执行。
function 回调函数名(data) {
console.log(data);
};
优点:
(1)由于使用script脚本作为请求,因此实际上请求和传统的引入js脚本没有任何区别。
(2)而在返回的数据中我们也尽量模拟出了js调用函数的语法,
因此只要在页面中声明了回调函数就会自动被调用。
(3)再者作为参数的【服务器端】的JSON数据,在js中是被直接识别为对象,
因此在回调函数中也避免了使用JSON.parse的步骤。
封装Ajax和跨域的更多相关文章
- 利用jquery的ajax实现跨域,内部其实是jsonp协议了,不是XHRhttp协议
一.同源策略 要理解跨域,先要了解一下“同源策略”.所谓同源是指,域名,协议,端口相同.所谓“同源策略“,简单的说就是基于安全考虑,当前域不能访问其他域的东西. 一些常见的是否同源示例可参照下表: 在 ...
- day78_淘淘商城项目_11_单点登录系统实现 + 用户名回显 + ajax请求跨域问题详解_匠心笔记
课程计划 1.SSO注册功能实现 2.SSO登录功能实现 3.通过token获得用户信息 4.ajax跨域请求解决方案--jsonp 1.服务接口实现 SSO系统就是解决分布式环境下登录问题的,本 ...
- AJAX POST&跨域 解决方案 - CORS
一晃又到新年了,于是开始着手好好整理下自己的文档,顺便把一些自认为有意义的放在博客上,记录成点的点滴. 跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是 ...
- 解决Ajax不能跨域的方法
1. Ajax不能跨域请求的原因 同源策略(Same Origin Policy),是一种约定,该约定阻止当前脚本获取或者操作另一个域下的内容.所有支持Javascript的浏览器都支持同源策略,也 ...
- AJAX POST&跨域 解决方案 - CORS(转载)
跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容),因为我们在日常的项目开发时会不可避免 ...
- jQuery的ajax jsonp跨域请求
了解:ajax.json.jsonp.“跨域”的关系 要弄清楚以上ajax.json.jsonp概念的关系,我觉得弄清楚ajax是“干什么的”,“怎么实现的”,“有什么问题”,“如果解决存在的问题”等 ...
- javascript ajax 脚本跨域调用全解析
javascript ajax 脚本跨域调用全解析 今天终于有点时间研究了一下javsscript ajax 脚本跨域调用的问题,先在网上随便搜了一下找到一些解决的办法,但是都比较复杂.由是转到jqu ...
- JavaScript(10)——Ajax以及跨域处理
Ajax以及跨域处理 哈哈哈,终于写到最后一章了.不过也还没有结束,说,不要为了学习而学习,恩.我是为了好好学习而学习呀.哈哈哈.正在尝试爱上代码,虽然有一丢丢的难,不过,我相信我会的! [Ajax] ...
- ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据的传递
前言 最近公司项目进行架构调整,由原来的三层架构改进升级到微服务架构(准确的说是服务化,还没完全做到微的程度,颗粒度没那么细),遵循RESTFull规范,使前后端完全分离,实现大前端思想.由于是初次尝 ...
随机推荐
- vue cli3.3 以上版本配置vue.config.js
// vue.config.js 配置说明//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions// 这里只 ...
- 我是如何在一周内拿到4份offer的?
前言 大概一个月没写博客了吧,这段时间事情比较多(家里有事,请了一段时间假,正好利用剩余几天时间面了几次试),也没抽出来时间写博客,还好所有的事情已经处理完了,今天闲来无事就整理一下这几次面试过程中遇 ...
- .NET webAPI中集成swagger
最近做的项目使用winform三层+webapi,对于webAPI路由文档管理一直觉得单独做一些管理比较麻烦,并且测试的时候项目内的代码测试运行起来也比较麻烦,所以在网上开始检索相关办法,发现热度比较 ...
- Educational Codeforces Round 71 (Rated for Div. 2)E. XOR Guessing
一道容斥题 如果直接做就是找到所有出现过递减的不同排列,当时硬钢到自闭,然后在凯妹毁人不倦的教导下想到可以容斥做,就是:所有的排列设为a,只考虑第一个非递减设为b,第二个非递减设为c+两个都非递减的情 ...
- API gateway 之 kong 安装 (二)
一.系统环境 [root@kong ~]# service iptables status iptables: Firewall is not running. [root@kong ~]# gete ...
- C++学习笔记1_ 指针.引用
1.引用的本质struct typeA{ int &a;}struct typeB{ int *a;}int main(void){ cout<<sizeof(struct typ ...
- IDEA 使用lombok
一.配置maven <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback ...
- 2019 .NET China Conf:路一直都在,社区会更好
这个周末,我从成都飞到了上海参加了首届由社区组织而非官方(比如Microsoft)组织的.NET开发者峰会(.NET Conf).为此,我特意请了两天的假(周五+周六,对,我们是大小周,这周六要上班) ...
- Apache配置反向代理、负载均衡和集群(mod_proxy方式)
Apache配置负载均衡和集群使用mod_jk的方式比较多,但是mod_jk已经停止更新,并且配置相对复杂.Apache2.2以后,提供了一种原生的方式配置负载均衡和集群,比mod_jk简单很多. 1 ...
- 易初大数据 2019年10月20日 linux死亡导图 王庆超