系统学习——Ajax & JSON_sKK07的博客-程序员宅基地

技术标签: 前端  系统学习  

Ajax基础

  • 示例
    function ajaxRequest () {
          
        // 实例一个XMLHttpRequest对象
        var xhr = new XMLHttpRequest();
        // open方法规定请求的类型、URL 以及是否异步处理请求。
        xhr.open("GET", "https://www.w3cschool.cn/statics/demosource/ajax_info.txt", true);
        // send将请求发送给服务器,需要与open一起使用
        xhr.send();
        // 在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务
        xhr.onreadystatechange = function(){
          
            // 当 readyState 等于 4 且状态为 200 时,表示响应已就绪
            if (xhr.readyState === 4 && xhr.status === 200) {
          
                document.getElementById("view").innerHTML = xhr.responseText;
            }                
        }
    }
    

同源策略

  • 同源策略是一种安全协议,是客户端脚本(尤其是 JavaScript)中重要的安全度量标准,指一段脚本只能读取同一来源的窗口和文档的属性。
  • 何为同源: 指的是 URL 地址中的 协议域名端口 三者都相同。
  • 跨域方法
    • 如果服务器端支持 CORS,可以通过设置Access-Control-Allow-Origin来实现跨域。如果浏览器检测到相应的设置,就会允许 Ajax 进行跨域访问。
    • JSONP 技术;
    • 在服务端设置代理模块;
    • 通过修改 window.name 实现跨域;
    • 使用 HTML5 中新引进的 window.postMessage 方法来跨域传送数据;
    • 等…

Ajax 的核心技术 XMLHttpRequest

  • 浏览器在XMLHttpRequest类上定义了 HTTP API,这个类的每个实例都表示一个 独立 的请求/响应对象,并且这个实例对象上的属性和方法允许指定细节提取响应数据

兼容

  • 在 IE7 之前的版本(IE5、IE6)并不支持XMLHttpRequest()构造函数,它们需要使用ActiveX对象进行模拟
    var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    

发起请求

  • xhr.open(method, url, async)
  • method:第一个参数用于指定 HTTP 请求的方法,不区分大小写;该参数可取的值包括:"GET"、"POST"、"HEAD"、"PUT"、"OPTIONS"、"DELETE",其中,“GET” 和 “POST” 是得到广泛支持的请求方法;
  • url:第二个参数用于指定 HTTP 请求的 URL 地址,可以是 绝对URL 或 相对URL;绝对URL:需要满足 “同源策略”(服务器明确允许跨域请求的情况除外);相对URL:即相对于文档的 URL;
  • async:第三个参数是可选的,可用布尔值指定脚本是否以异步的方式调用此次 Ajax 请求;该参数默认为 true,表示异步调用此次 Ajax 请求,不阻塞后续脚本的执行;
  • xhr.setRequestHeader(name, value)
  • 如果对相同的头调用setRequestHeader多次,新值不会取代之前指定的值,相反,HTTP 请求将包含这个头的多个副本或将这个头指定多个值。
  • 你不能自己指定 “Content-Length”、"Date"、"Referer" 或 “User-Agent” 头,XMLHttpRequest将自动添加这些头而防止伪造它们。类似地,XMLHttpRequest对象还会自动处理 cookie链接时间字符集和编码判断,所以你无法使用setRequestHeader方法设置它们。
  • xhr.send()
  • 由于 GET 请求 绝对 没有请求主体,所以在调用 send 方法时可以传递 null 或 省略这个参数;
  • POST 请求通常都拥有请求主体,可在 send 方法中指定它.
  • POST 请求的请求主体,应该匹配setRequestHeader方法所指定的 “Content-Type” 头。
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "/statics/demosource/demo_post_json.php");
    
    // 在 open 方法之后设置请求头
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    
    // 无请求主体
    // xhr.send(null);
    // 把 msg 作为请求主体发送
    xhr.send(msg);
    

取得响应

  • 一个完整的 HTTP 响应由状态码响应头响应主体组成。
  • 为了能够在 HTTP 响应准备就绪时得到通知,必须监听XMLHttpRequest对象上的readystatechange事件。
  • readyState属性是一个整数,它的值代表了不同的 HTTP 请求状态。
    • 0:初始值,表示请求未初始化,open方法尚未调用;
    • 1:启动请求,open 方法已经调用,但尚未调用 send 方法;
    • 2:请求发送,已经调用 send 方法,但尚未接收到响应;
    • 3:接收响应,已经接受到部分响应数据,主要是响应头;
    • 4:HTTP 响应完成,已经接收到全部响应数据,而且可以在客户端使用。
  • readyState的属性值只代表此时的 HTTP 请求处于哪个阶段:是发送了请求还是未发送请求,是只接收到了响应头还是响应完成;
  • “响应完成” 只代表 HTTP 请求结束,至于服务器的响应状态:是请求成功还是请求错误,又或者是服务器错误,需要通过 HTTP 状态码判断,它存储在XMLhttpRequest的status属性上。
  • status属性会以数字的形式保存服务器响应的 HTTP 状态码。
    • 1xx:临时响应
    • 2xx:成功
    • 3xx:重定向
    • 4xx:请求错误
    • 5xx:服务器错误
  • 2开头的状态码304。2开头的状态码都表示请求成功,而 304 是对客户端可读取缓存的一种响应,同样能获取到 HTTP 的响应数据。
  • 响应主体有时还可以从XMLHttpRequest对象的responseresponseXML属性获取
    • responseText:无论返回的数据类型是什么,响应主体的内容都会保存在responseText属性中;
    • responseXML:只对 XML 数据有效,若响应主体是非 XML 数据,该属性值为null;
    • response:通常配合responseType使用。若指定了XMLHttpRequest实例的responseType属性,则将响应内容转换为该属性所指定的格式并返回,否则按默认情况处理。
    • 若指定了responseType的值为非 “text” 或 非空,则responseText属性就会失效,因此时的响应主体已不再是 “text” 文本形式,继续使用它获取响应主体浏览器会给出相应的报错信息
    var xhr = new XMLHttpRequest();
    var timer = null;  //用于存储定时器标识
    // 指定响应主体的数据格式为 json
    // xhr.responseType = "json";
    
    xhr.onreadystatechange = function () {
          
        if (xhr.readyState !== 4) return;
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
          
       		 clearTimeout(timer);//请求成功清除计时器
       		 
            // 当响应成功,获取响应数据,将数据赋值给本地
            oView.innerHTML = xhr.responseText;
            
    		// 使用JSON.parse把 响应数据转换为json数据
      		var res = JSON.parse(xhr.responseText);
      	  	// 将响应数据中的date属性赋值给oTime做内容
     	   	oTime.innerText = res.date;
     	   	
     	   	// 指定响应主体的数据格式为 json后,从这里取数据。
    		// oTime.innerText = xhr.response.date;
    
        } else {
          
            alert("请求失败,HTTP 状态码为:" + xhr.status);
        }
    };
    //2秒后中止此次请求
    timer = setTimeout(function(){
          
    	xhr.abort();
    },2000)
    
    xhr.open("GET", "/statics/demosource/404.txt");
    xhr.send();
    
  • getAllResponseHeaders方法无参数,用于一次性返回可查询的全部响应头信息。
  • getResponseHeader方法用于查询单一响应头信息,需要传入一个指定 “头名称” 的字符串作为参数。
  • 由于XMLHttpRequest会自动处理 cookie,将 cookie 从getAllResponseHeaders方法返回的响应头集合中过滤掉,并且如果给getResponseHeader方法传递 “Set-Cookie” 或 “Set-Cookie2”,则返回 null

同步请求

  • false作为第三个参数传递给open方法,那么调用send方法将 阻塞 后续脚本的执行 直到 HTTP 请求完成。在这种情况下,不再需要监听readystatechange事件,因为send方法后面的代码一定会等到 HTTP 请求完成后再执行。
  • JavaScript 脚本是 单线程 的,当send方法阻塞脚本时,往往会导致整个页面被冻结。

请求中止

  • HTTP 请求的时间超出预期,可以调用XMLHttpRequest对象上的abort方法来中止 HTTP 请求。

前后端数据交互

GET 请求的缓存

  • 对于 GET 请求,请求的结果会被浏览器缓存,特别是在 IE 浏览器下。这时,如果 GET 请求的 URL 不变,那么请求的结果就是浏览器的缓存(也就是上次 GET 请求的结果)。

封装AjaxGet


        function ajaxGet (url, data, success, error) {
    
            var xhr = new XMLHttpRequest();
            xhr.open("GET",url);
            xhr.send();
            xhr.onreadystatechange() = function(){
    
                if(xhr.readyState !==4) return;
                if((xhr.status >=200 && xhr.status <300) || xhr.status==304){
    
                    var res = JSON.parse(xhr.responseText);
                    success(res);
                }else{
    
                    error(xhr.status);
                }
            }
        }
        
        // 用于对 JavaScript 对象执行普通的 URL 编码
        // 编码后的格式为:"名称=值&...&名称=值"
        function urlencodeData (data) {
    
            if (!data) return;
            var pairs = [];
            for (var name in data) {
    
                if (!data.hasOwnProperty(name)) continue;
                if (typeof data[name] === "function") continue;
                var value = (data[name] === null || data[name] === undefined) ? "" : data[name].toString();
                pairs.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
            }
            return pairs.join("&");
        }

封装AjaxPost

        function ajaxPost (url, data, success, error) {
    
     
             var xhr = new XMLHttpRequest();
            xhr.open("POST",url);
            xhr.setRequestHeader('Content-Type','application/json');
            
            xhr.send(JSON.stringify(data));
            
            xhr.onreadystatechange() = function(){
    
                if(xhr.readyState !==4) return;
                if((xhr.status >=200 && xhr.status <300) || xhr.status==304){
    
                    var res = JSON.parse(xhr.responseText);
                    success(res);
                }else{
    
                    error(xhr.status);
                }
            }
        }
        
        // 用于对 JavaScript 对象执行普通的 URL 编码
        // 编码后的格式为:"名称=值&...&名称=值"
        function urlencodeData (data) {
    
            if (!data) return;
            var pairs = [];
            for (var name in data) {
    
                if (!data.hasOwnProperty(name)) continue;
                if (typeof data[name] === "function") continue;
                var value = (data[name] === null || data[name] === undefined) ? "" : data[name].toString();
                pairs.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
            }
            return pairs.join("&");
        }

jQuery中的Ajax

  • $.ajax(url, options)
  • $.get(url, data, callback, dataType)
  • $.post(url, data, callback, dataType)
  • $.getJSON(url, data, callback)
  • $.getScript(url, callback)
  • jQuery元素.load(url, data, callback)

JSON

  • JSON 语法可以表示 JavaScript 中的简单值(除undefined)、对象 、数组。
  • JSON字符串 与 JavaScript字符串 的最大区别在于,JSON 字符串必须使用 双引号,单引号会导致语法错误。
  • 与 JavaScript 的字面量相比,JSON 对象的键(属性名) 必须双引号

JSON.stringify()

  • 用于序列化 JavaScript 对象,将其转换为 JSON 字符串;

JSON.parse()

  • 用于解析 JSON 字符串,将其转换为 JavaScript 值。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhaoguang2018/article/details/104537458

智能推荐

Java 8:当重载遇上lambda_jdk8 lambda 方法重载问题__从头再来_的博客-程序员宅基地

要设计出好的API绝非易事。真的是很不容易。如果你希望用户能给你的API点个赞的话,设计的时候需要考虑得非常周全。你必须得在以下几点中找到一个平衡点:实用性 可用性 向后兼容 向前兼容我在前面的优秀的API是如何炼成的一文中也提到了同样的问题。今天,我们来看一下,Java 8是如何破坏了这个游戏规则的:没错,就是破坏。重载的便利性主要体现在以下两个方面:提供了不同的..._jdk8 lambda 方法重载问题

Nginx学习笔记_这样很好的博客-程序员宅基地

1、安装Nginx1:去官网http://nginx.org/下载对应的nginx包,推荐使用稳定版本。2:上传nginx到linux系统3:安装依赖环境(1)安装gcc环境yum install gcc-c++(2)安装PCRE库,用于解析正则表达式yum install -y pcre pcre-devel(3)zlib压缩和解压缩依赖yum install -y zlib...

使用flex 布局时,英文不自动换行_flex 超出自动换行英文不能换行-程序员宅基地

问题场景:在使用 flex 布局时,当内容超出宽度时的换行问题问题描述:flex 布局时,内容超过盒子宽度时,当内容为中文时会自动换行显示,而内容是一串英文字符或者数字时,就不会自动换行显示,如下图:<div class="grid"> <div class="grid-cell"> <span>Flex 是 Flexible Box 的缩写,意为"弹性布局"。Flex 是 Flexible Box 的缩写,意为"弹性布局"。&l_flex 超出自动换行英文不能换行

iOS presentViewController 推出半透明窗口简单的实现方式_赛BING的博客-程序员宅基地

阅读 正确使用PresentModalViewController 后,并参考了其他大牛的方法有所心得。要想实现presentViewController 推出半透明窗口并不是那么难。 ChooseLocationController *locationVc = [[ChooseLocationController alloc]init]; [locationVc setModalPres...

hadoop job 抛出 Exception in thread "main" java.lang.NoClassDefFoundError: ___/tmp/hsperfdata_ 异常_/tmp/hsperfdata_pmoopr/1358290 (deleted)_小胖头鱼的博客-程序员宅基地

hadoop的job抛出以下异常:Exception in thread "main" java.lang.NoClassDefFoundError: ___/tmp/hsperfdata_pctvlog/11835Caused by: java.lang.ClassNotFoundException: ___.tmp.hsperfdata_pctvlog.11835_/tmp/hsperfdata_pmoopr/1358290 (deleted)

STL总结之priority_queue_为什么priority_queue需要strcut_YangLei253的博客-程序员宅基地

介绍priority_queue 是容器适配器,它提供程序员堆数据结构的功能。priority_queue 底层容器有两种可选—— vector、deque,默认使用 vector。priority_queue 定义于头文件 <queue> 中 ,其声明如下:template< class T, class Container = std::vector&..._为什么priority_queue需要strcut

随便推点

HDOJ1001_Whale-Song的博客-程序员宅基地

Problem DescriptionI have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum of A + B.InputThe first line of the input contains an integer T(1<=T<=20) which mea_hdoj1001

SonarQube安装及使用_4ajt_scluis的博客-程序员宅基地

前言最近需要使用SonarQube分析一下项目,简单记录一下下载安装和使用过程。下载安装7.4版本下载地址:链接:https://pan.baidu.com/s/1TBrO0kSy_5HOpbRUxzeDRw提取码:4ajt下载SonarQube之前,需要已经配好了JDK和MySQL的环境(数据库也可以不用MySQL)我这里使用的是JDK8和MySQL5.6.40,SonarQube使用的是7.4版本,一开始下载了最新版本(8.9),发现需要JDK11才能使用,果断放弃了,下载了支持JDK8的_4ajt

mysql数据库版本从5.6.28升到8.0.11,部署项目遇到的问题。_bwl1988926的博客-程序员宅基地

mysql数据库版本从5.6.28升到8.0.11,部署项目遇到的问题。首先这个项目用到了hibernate4.2.0,链接mysql5.6.28没问题,换到8.0.11,启动报错1.Caused by: org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set报错就配置...

Java 定时器 Quzrtz 的集成使用_Li_WenZhang的博客-程序员宅基地

Java 定时器 Quzrtz 的集成使用 1. 实现思路 1) 导入依赖Jar包(Spring和Quartz) 2) 编写定时任务(TestJob 类) 3) 配置Spring参数,配置定时任务的运行时间 4) 编写测试用例,运行测试、输出测试结果 5) 其他。

AJAX网络请求 —— 简单的发送一个FormData表单数据(二)_ajax 提交formdata_wincheshe的博客-程序员宅基地

文章目录FormData发送一个简单的表单FormData 方法发送带有文件的表单发送具有 Blob 数据的表单总结FormData这一章是关于发送 HTML 表单的:带有或不带文件,带有其他字段等。FormData 对象可以提供帮助。你可能已经猜到了,它是表示 HTML 表单数据的对象。构造函数是:let formData = new FormData([form]);如果提供了 HTML form 元素,它会自动捕获 form 元素字段。FormData 的特殊之处在于网络方法(netw_ajax 提交formdata

Matplotlib-程序员宅基地

简介Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。官方网站:https://matplotlib.org/安装pip安装:pip install matplotlib -i https://mirrors.aliyun.com/pypi/simple/导入模块名字有点长,建议导入后用as起个别名:imp..._plt 随机生成多个颜色

推荐文章

热门文章

相关标签