前端总结·基础篇·JS(四)异步请求及跨域方案
前端总结系列
- 前端总结·基础篇·CSS(一)布局
- 前端总结·基础篇·CSS(二)视觉
- 前端总结·基础篇·CSS(三)补充
- 前端总结·基础篇·JS(一)原型、原型链、构造函数和字符串(String)
- 前端总结·基础篇·JS(二)数组深拷贝、去重以及字符串反序和数组(Array)
- 前端总结·基础篇·JS(三)arguments、callee、call、apply、bind及函数封装和构造函数
- 前端总结·基础篇·JS(四)异步请求及跨域方案
- 前端总结·工具篇·管理(一)常用模块化方案
目录
一、异步请求
1.1 XHR(XMLHttpRequest)
1.2 Promise(ES6)
1.3 Fetch
二、跨域方案
2.1 JSONP(JavaScript Object Notation with Padding)
2.2 CORS(Cross-origin resource sharing)
一、异步请求
此文只进行简单的介绍,完整的用例请见我的Github。Github上的用例,对这三种方法的POST和GET请求都进行了封装。
Github演示不支持POST请求,所以会有部分报错。完整测试可以放在本机的localhost下。
a.json
-------------
{
"user":"张三",
"folling":30,
"foller": 20
}
1.1 XHR(XMLHttpRequest)
三行代码实现异步请求
下面是发送XHR请求之后,返回的成功信息。
<script type="text/javascript">
var xmlhttp = new XMLHttpRequest() // 创建异步请求
xmlhttp.open('GET','a.json') // 使用GET方法获取hello.txt文件
xmlhttp.send() // 发送异步请求
</script>
读取异步请求返回的数据
返回的数据存储在xmlhttp.responseText。
怎么返回了这么多内容?请接着往下看。
<script type="text/javascript">
var xmlhttp = new XMLHttpRequest()
// 异步请求状态发生改变时会执行这个函数
xmlhttp.onreadystatechange = function () {
// 显示返回的内容
console.log(xmlhttp.responseText)
}
xmlhttp.open('GET','hello.txt')
xmlhttp.send()
</script>
异步请求的状态
现在就好了,我们在使用xmlhttp.responseText之前判断了一下当前ajax的状态。确认完成了,我们才返回值。
<script type="text/javascript">
var xmlhttp = new XMLHttpRequest()
xmlhttp.onreadystatechange = function () {
// status == 200 用来判断当前HTTP请求完成
if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
console.log(xmlhttp.responseText)
}
}
xmlhttp.open('GET','hello.txt')
xmlhttp.send()
</script>
异步请求一共有五个状态,用来标识异步请求的不同阶段。
- 0 UNSENT 代理被创建,但尚未调用 open() 方法
- 1 OPENED open() 方法已经被调用
- 2 HEADERS_RECEIVED send() 方法已经被调用,并且头部和状态已经可获得
- 3 LOADING 下载中; responseText 属性已经包含部分数据
- 4 DONE 下载操作已完成
上面返回的五条数据中,一条是XHR请求成功默认返回的。前两条对应的状态1和2,是没有返回内容的,所以为空。后面两条有内容的对应的是3和4。
因此,我们想要数据完全下载完成了再显示返回内容,只需要用if判断一下当前状态是否是4即可。
关于HTTP状态码代表的意义,可以看我之前写过的文章。
封装XHR方法
function ajax (method,url,callback) {
var xmlhttp = new XMLHttpRequest() // 创建异步请求
// 异步请求状态发生改变时会执行这个函数
xmlhttp.onreadystatechange = function () {
// status == 200 用来判断当前HTTP请求完成
if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
callback(JSON.parse(xmlhttp.responseText)) // 执行回调
}
}
xmlhttp.open(method,url) // 使用GET方法获取
xmlhttp.send() // 发送异步请求
}
调用XHR方法
ajax('GET','a.json',function (res) {
console.log(res) // 显示返回的对象
ajax('GET','b.json',function (res) {
console.log(res)
ajax('GET','c.json',function (res) {
console.log(res)
})
})
})
1.2 Promise(ES6)
我们在用Ajax写异步的时候,很容易掉入回调地狱(callback),代码的可读性会大大的下降。Promise可以让代码变得更优雅。
封装基于Promise的XHR
function ajax ( method,url ) {
// 返回一个Promise对象
return new Promise(function (resolve) {
var xmlhttp = new XMLHttpRequest() // 创建异步请求
// 异步请求状态发生改变时会执行这个函数
xmlhttp.onreadystatechange = function () {
// status == 200 用来判断当前HTTP请求完成
if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
resolve(JSON.parse(xmlhttp.responseText)) // 标记已完成
}
}
xmlhttp.open(method,url) // 使用GET方法获取
xmlhttp.send() // 发送异步请求
})
}
调用基于Promise的XHR
var aj = ajax('GET','a.json')
aj.then(function (res) {
console.log(res)
})
1.3 fetch
fetch是对Promise的一个封装,使用非常方便。
fetch('a.json').then(function (res){
return res // 返回Promise
}).then(function (res) {
return res.json() // 返回JSON对象
}).then(function (json) {
console.log(json) // 显示JSON内容
})
二、跨域方案
CORS方法更好一些,但是需要对服务器有自主权。JSONP则不需要对服务器有自主权,可以通过script、img等标签可以发送GET请求的特点,通过回调函数执行已有的JS函数。在函数内获取返回值。
CORS支持所有HTTP请求,JSONP只支持GET请求。
2.1 JSONP(JavaScript Object Notation with Padding)
用回调跨域
------------------------
<script type="text/javascript" src="http://localhost/async/cors.php?callback=go"></script>
设置好回调函数
------------------------
function go (arr) {
console.log(arr) // 显示回调的值 | {a:"1"}
}
script发送的GET请求时,返回的值是一个函数,遂执行回调函数
------------------------
<?php
$go=$_GET['callback']; // 获取callback的值
echo $go.'({a:"1"})'; // 输出回调函数
?>
2.2 CORS(Cross-origin resource sharing)
PHP配置CORS
<?php
header("Access-Control-Allow-Origin:*"); // *号为允许所有域名,推荐修改成需要跨域的域名
?>
配置CORS前
配置CORS后
总结
下一篇总结Vue。
参考
- AJAX - MDN
- XMLHttpRequest - MDN
- XHR——XMLHttpRequest对象 - gaojun
- XMLHttpRequest 对象 - W3Scool
- 跨域资源共享 CORS 详解 - 阮一峰
- JavaScript异步编程(1)- ECMAScript 6的Promise对象 -
- fetch使用的常见问题及解决办法 - wonyun
- 你不需要jQuery(三):新AJAX方法fetch() - 唸随爱
- 深入浅出Fetch API 带你入解应用场景及适用问题 - Ludovico Fischer
前端总结·基础篇·JS(四)异步请求及跨域方案的更多相关文章
- 前端总结·基础篇·JS(一)五大数据类型之字符串(String)
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(二)补充 前端总结·基础篇·JS(一)五大数据类型之字符串(String) 目录 这是& ...
- 前端总结·基础篇·JS(二)数组深拷贝、去重以及字符串反序和数组(Array)
目录 这是<前端总结·基础篇·JS>系列的第二篇,主要总结一下JS数组的使用.技巧以及常用方法. 一.数组使用 1.1 定义数组 1.2 使用数组 1.3 类型检测 二.常用技巧 2.1 ...
- 前端总结·基础篇·JS(三)arguments、callee、call、apply、bind及函数封装和构造函数
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...
- 前端总结·基础篇·JS(一)原型、原型链、构造函数和字符串(String)
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...
- 一篇搞定vue请求和跨域
vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 axios是一个基本Promise的HTTP请求客户端,用来发送请求,也是vue2.0官方推荐的,同时不再对v ...
- Vue--axios:vue中的ajax异步请求(发送和请求数据)、vue-resource异步请求和跨域
跨域原理: 一.使用axios发送get请求 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 & ...
- 关于Ajax的get与post浅分析,同步请求与异步请求,跨域请求;
Ajax局部异步刷新全称ASynchronous JavaScript And XML.使用Javascript代码获取服务器的数据,Ajax当中有两个请求方法,一个是get方法,一个是post请求方 ...
- 前端总结·基础篇·CSS(一)布局
目录 这是<前端总结·基础篇·CSS>系列的第一篇,主要总结一下布局的基础知识. 一.显示(display) 1.1 盒模型(box-model) 1.2 行内元素(inline) &am ...
- 前端总结·基础篇·CSS(二)视觉
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·CSS(四)兼容 目录 一.动画(animation)(IE ...
随机推荐
- hadoop编译
说明: hadoop版本:hadoop-2.5.0-cdh5.3.6 环境:centos6.4 必须可联网 hadoop 下载网址: http://archive.cloudera.com/cdh5/ ...
- 认识ionic2
1. Ionic 2 介绍 Ionic 2专注于以标准的HTML.CSS和JavaScript来构建移动站点,并可以通过Cordova打包成移动 App,只需编写一次代码,就可以分别部署到iOS.An ...
- toupper函数及一些小程序
toupper 原型:extern int toupper(int c); 用法:#include <ctype.h> 功能:将字符c转换为大写英文字母 说明:如果c为小写英文字母,则返回 ...
- 【问题解决】使用自定义控件时,vs停止工作
问题表现:向页面中添加自定义控件时,vs卡住了,随便点击一下,然后窗口未响应,然后用资源管理器看到内存使用在飙升,监视进程会发现就是vs的进程出现了异常 问题的解决:菜鸟D在网上搜了一下,发现一个奇葩 ...
- Java源码ExtJS 5 SpringMVC 4Hibernate 4通用后台管理开发框架
需要源码,请加QQ:858-048-581 一.特色1.采用Spring MVC的静态加载缓存功能,在首页将Javascript文件.CSS文件和图片等静态资源文件加载进来放进内存,极大提高ExtJS ...
- smarty模板基础1
smarty模板的作用可以让前端和后端分离(也就是前端的显示页面和后端的php代码). smarty模板的核心是一个类,下载好的模板中有这么几个重要的文件夹 (1)libs核心文件夹(2)int.in ...
- H5微场景宽、高度自适应办法
最近在做一些手机端微场景,发现处理各种手机屏幕分辨率是个很让人头疼的事情,最终找到了一个处理效果比较满意的方案.各位客观请往下看: 如果有过做微场景经历的客官们应该都了解,在代码中给一个元素的宽高设成 ...
- AndroidStudio运行项目出现Unsupported method: AndroidProject.getPluginGeneration()错误解决办法
一.错误描述 今天在使用AndroidStudio运行项目时出现了一个Unsupported method: AndroidProject.getPluginGeneration()错误,如下图所示: ...
- SQLServer索引循环删除
declare qc_cursor cursor SCROLL OPTIMISTIC Forselect siteName from tb_vhostcheckopen qc_cursordeclar ...
- wemall开源商城免费商城系统部分代码(内含代码地址)
wemall开源商城免费商城系统部分代码,下面分享部分代码,供学习者学习: 开源版把install文件夹下的install.lock删除之后可进行自动安装 后台访问地址:http:// www.xxx ...