AJAX之封装+跨域

2 篇文章 0 订阅
1 篇文章 0 订阅

AJAX5步法

  • 先简单回顾下之前所说的5步法
    1、创建异步对象XMLHttpRequest
/* 1.创建 XMLHttpRequest一步对象*/
			var xhr;
			if (window.XMLHttpRequest) {
				xhr = new XMLHttpRequest(); /* 主流浏览器 */
			} else {
				xhr = new ActiveXObject("Microsoft.XMLHTTP"); /* 兼容IE写法 */
			}

2、设置回调函数

/* 2.设置回调函数*/
			xhr.onreadystatechange = callback;

3、open()方法连接服务器

/* 3.使用open方法与服务器建立连接 */
			xhr.open("get", "naonao.text", true)

4、send()方法发送数据至服务器

/* 4.注册事件,设置和服务器的交互信息,向服务器发送数据 */
			xhr.send()

5、回调函数中针对不同响应状态进行处理,局部更新界面
这里先获取下返回数据,reponseText表示以字符串形式接收服务器端返回信息

function callback() {
				if (xhr.readyState == 4 && xhr.status == 200) {
						console.log(xhr.responseText)
					}
				}
  • 完整代码如下所示
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}

			div {
				border: 1px solid red;
				margin: 50px;
			}

			p {
				border: 1px solid blue;
			}
		</style>
	</head>
	<body>
		<button name="ajax">ajax</button>
	</body>
	<script type="text/javascript">
		var btn = document.querySelector("button[name='ajax']");
		console.log(btn)
		btn.addEventListener('click', callback, false) /* false是事件冒泡,true是事件捕获,不写的话默认是false。 */
		function callback() {
			/* 1.创建 XMLHttpRequest一步对象*/
			var xhr;
			if (window.XMLHttpRequest) {
				xhr = new XMLHttpRequest(); /* 主流浏览器 */
			} else {
				xhr = new ActiveXObject("Microsoft.XMLHTTP"); /* 兼容IE写法 */
			}
			console.log(xhr)
			/* 2.设置回调函数*/
			xhr.onreadystatechange = callback;

			/* 3.使用open方法与服务器建立连接 */
			xhr.open("get", "naonao.text", true)
			/* 4.注册事件,设置和服务器的交互信息,向服务器发送数据 */
			xhr.send()
			/* 5.回调函数处理---响应---针对不同的响应状态进行处理 */
			function callback() {
				if (xhr.readyState == 4 && xhr.status == 200) {
					var responseText = xhr.responseText;
					console.log(responseText)
					var xhrObject = JSON.parse(responseText)
					console.log(xhrObject)
					var new_div = document.createElement('div');
					document.body.appendChild(new_div);
					for (var i = 0; i < xhrObject.length; i++) {
						var new_p = document.createElement('p');
						var new_string = "";
						new_string += "姓名:" + xhrObject[i].name;
						new_string += " &nbsp 年龄:" + xhrObject[i].age;
						new_p.innerHTML = new_string;
						new_div.appendChild(new_p)
					}
				}
			}
		}
	</script>
</html>

  • 接下来测试下get请求类型,将open连接服务器步骤里的请求类型设置为get,如下所示
xhr.open("get", "naonao.text")
  • 利用HBuilderX编辑器打开(启动时自带本地服务器)如下所示
    JSON数据无法直接在页面进行操作,所以需要先将JSON字符串转成JS普通对象数组型数据。
    在这里插入图片描述
  • 接下来转换JSON数据为普通JS对象型,如下所示
    在这里插入图片描述

AJAX封装

  • 【前言】
    • 目前为止,已经实现基本功能,但AJAX的调用还十分麻烦,步骤比较繁琐,在日常开发一般会将其进行封装,所以接下来封装下AJAX功能相关步骤函数,以后使用直接调用即可,同时大大提高了开发效率。
    • 为了使用方便,接下来封装AJAX的get和post
      封装:基本模板与传参
/* url路径,data是否携带参数,method请求类型,success成功后返回值 */
			function ajax(url, data, method, success) {

			}

此时调用模板时,如下所示

/* 注意:因为get方法里没有参数,所以这里第二个参数设置为unll */
			ajax('index.tet',unll,'get',function(){
				/* 回调函数 */
			})			

封装1:建立异步对象

function ajax(url, datd, method, success) {
				/* 1.建立异步对象 */
				var xhr;
				if (window.HML.HttpRequest) {
					xhr = new XMLHttpRequest();
				} else {
					xhr = new ActiveXObject('Microsoft.XMLHTTP');
				}
			}

封装2:判断请求类型

function ajax(url, datd, method, success) {
				/* 1.建立异步对象 */
				var xhr;
				if (window.HML.HttpRequest) {
					/* 2.判断请求类型 */
					if (method == 'get') {
						/* get请求类型 */
					} else {
						/* post请求类型 */
					}
				}
			}
  • 封装2:判断请求类型
    • get请求类型传值方式是将数据拼接到路由后进行传值,所以接下来需要判断是否传值(对比post请求),回顾之前所讲
      在这里插入图片描述
      1、get请求类型传值方式是将数据拼接到路由后进行传值
					/* 2.判断请求类型 */
					if (method == 'get') {
						/* get请求类型 */
						if (datd) {
							url += '?';
							url += datd;
						}
						xhr.open(method, url)
						xhr.send();
					} else {
						/* post请求类型 */
					}

2、post请求类型判断是否有传值,如果有则send发送至服务器,没有则不发

						/* post请求类型 */
						xhr.open(method, url);
						if (data) {
							xhr.send(data);
						} else {
							xhr.send()
						}

封装3:注册事件,针对不同状态进行响应,获取返回数据

/* 3.注册事件,针对不同的状态进行响应,获取返回数据 */
			xhr.onreadystadechange = function() {
				if (xhr.readyStade == 4 && xhr.status == 200) {
					/* 4.成功后执行回调函数
						获取返回数据,reponseText表示以字符串的形式接收服务器端返回的信息
						然后将其传到调用处
					 */
					success(xhr.responseText);
				}
			}
  • 开发中,也可以将响应,即注册事件步骤,直接移至第一步创建异步对象下,以便更好地监听到状态变化。
  • 封装调用:
    • 接下来外部传参调用下封装的AJAX函数
      最后的匿名函数对应AJAX函数中封装的success成功回调,success里传参reponseText表示以字符串形式接收服务器端返回信息
ajax('index.txt', unll, 'get', function(option) {
				/* 回调函数 */
				console.log(option)
			})
  • 此时控制台测试,便可以输出打印JSON格式数据,所以如果想用JS进一步操作,需要进行反序列化解析即JSON.parse(),然后操作其对页面进行局部更新。
ajax('index.txt', unll, 'get', function(option) {
				/* 回调函数 */
				console.log(option); /* JSON格式 */
				console.log(JSON.parse(option)); /* 普通js对象数组格式 */
			})

在这里插入图片描述

  • 跨域简介:
    AJAX跨域指的是JS在不同的域之间进行数据传输或通信。
  • 跨域方案:
    • 1、jsonp跨域(重点)----前端处理方法
    • 2、cros跨域-----后台处理
  • 常见跨域场景?
    • 所谓的同源是指,域名、协议、端口均为相同。
      http://www.nealyang.cn/index.html 调用 http://www.nealyang.cn/server.php 非跨域
      http://www.nealyang.cn/index.html 调用 http://www.neal.cn/server.php 跨域,主域不同
      http://abc.nealyang.cn/index.html 调用 http://abc.neal.cn/server.php 跨域,子域名不同
      http://www.nealyang.cn:8080/index.html 调用 http://www.nealyang.cn/server.php 跨域,端口不同
      https://www.nealyang.cn/index.html 调用 http://www.nealyang.cn/server.php 跨域,协议不同
      localhost 调用 127.0.0.1 跨域

AJAX跨域-JSONP

  • JSONP跨域:
    • jsonp跨域原理:借助网页标签中src属性的跨域特性实现
    • src简介:src是source的缩写,资源的意思,在html中src表示资源地址,是js文件和图片文件的引入方式,经常引用外部资源,可以实现跨域访问,如下所示
      在这里插入图片描述
  • 接下来调用下百度搜索接口,如下所示
    https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/?wd=&cb=
    解析:
    wd为搜索关键词,百度搜索功能发送请求类型为get,因为所搜的关键词可以在url中可见。这里先不用回调
    在这里插入图片描述
  • 将之前代码做下调整,将url改为百度搜索接口,如下所示
    在这里插入图片描述
  • 注意:
    因为是get方式,所以关键词传值需要拼接到url里,即通过data传参,且参数为想要的关键词,然后之前封装好的AJAX会将其进行封装,也就是说最后send对应的接口url为经过封装的AJAX函数拼接后的地址
    https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/?wd=海贼王
  • 将之前代码做下调整,将url改为百度搜索接口,如下所示
    在这里插入图片描述
  • 接下来使用JSONP实现跨域,本质利用src属性的跨域请求资源特性,同理<script></script>脚本标签也是通过src引入资源,所以可以进行封装处理,实现AJAX的跨域访问远程资源。
  • 接下来做下测试,script标签引入接口文件,并在接口加入回调函数,然后在页面定义调用
    在这里插入图片描述
  • 测试结果如下
    在这里插入图片描述
  • 此时虽然有报错,但是已经没有报跨域错误,接下来将调用位置做下调整,先定义声明函数,然后再进行传值,如下所示
<script type="text/javascript">
		function callback(option) {
			console.log(option)
		}
	</script>
	<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/?wd=666&cb=callback">
</script>
  • 修改后测试结果如下
    由此分析出,可以通过src属性实现跨域调取资源。但JSONP为动态插入,所以接下来还需要进行调整,之后介绍。
    在这里插入图片描述
  • 除了通过JSONP解决跨域外,常见的方法还包含CROS方法
  • 【前言】
    • CROS需要在后台进行配置→允许所有域名访问
      • 1、PHP后台仅仅需要添加一句代码即可header(’ Access-Control-Allow-Origin : * '); 表示允许所有域名访问。
      • 2、JAVA后台需要下载CROS包,然后进一步配置

小结

  • 目前为止,讲解了JSONP跨域原理和CROS跨域方案
    • 下节利用前端JSONP实现“百度关键词”跨域案例。
  • 完整的代码如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>ajax</title>
		<style>
			input[name="search"]{
			    text-indent: 10px;
			    height: 40px;
			    line-height: 24px;
			    width: 472px;
			    border: 1px solid rgba(0,0,0,.3);
			    outline: 0;
			    background: #FFF;
			    overflow-y: visible;
    			font-size: 100%;
    			color: #000;
    			vertical-align: middle;
			}
			.btn{
				font-size: 18px;
			    font-weight: 700;
			    color: #FFF;
			    background-color: #FF4200;
			    cursor: pointer;
			    height: 40px;
			    border: none;
			    width: 74px;
			    background-image: linear-gradient(to right,#ff9000 0,#ff5000 100%);
    			background-repeat: repeat-x;
			}
			#menu_ul{
				padding: 0;
				margin: 0;
				position: absolute;
				left: 8px;
				top: 54px;
				height: auto;
				width: 470px;
				border: 1px solid rgba(0,0,0,.6);
			}
		</style>
	</head>
	<body>
		<!-- <img src="https://www.baidu.com/img/bd_logo1.png?qua=high" /> -->
		<input type="text" name="search" placeholder="请输入商品关键字"/>
		<button class="btn">搜索</button>
		<ul id="menu_ul"></ul>
		<script>
			var searchInput = document.querySelector('input[name="search"]');
			console.log(searchInput)
			searchInput.addEventListener('keyup',function(){
				if(document.querySelector("#new_script_id")){
					document.querySelector("#new_script_id").remove();
				}
				console.log(this.value)
				var new_script = document.createElement('script');
				new_script.src = "http://suggest.taobao.com/sug?code=utf-8&q="+this.value+"&callback=cb";
				new_script.id = "new_script_id";
				document.body.appendChild(new_script)
			},false)
			/*回调*/
			var menu_ul = document.querySelector("#menu_ul");
			function cb(option){
				console.log(option)
				var str = "";
				for(var i=0;i<option.result.length;i++){
					str+="<li>"+option.result[i][0]+"</li>"
				}
				menu_ul.innerHTML = str;
			}
		</script>
        <!--<script src="ajax.js"></script>
        <script>
        	ajax('https://tcc.taobao.com/cc/json/mobile_tel_segment.htm','tel=15731197042','get',function(data){
        		console.log(data)
        		console.log(JSON.parse(data))
        	})
        </script>-->
	</body>
</html>

完毕…

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

裴嘉靖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值