系统学习——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

智能推荐

机器学习---生成模型与判别模型_吃不胖的卷卷的博客-程序员宅基地

生成模型(Generative Model)是相对于判别模型(Discriminative Model)定义的。他们两个都用于有监督学习。监督学习的任务就是从数据中学习一个模型(也叫分类器),应用这一模型,对给定的输入X预测相应的输出Y。这个模型的一般形式为决策函数Y=f(X)或者条件概率分布P(Y|X)。       决策函数Y=f(X):你输入一个X,它就输出一个Y,这个Y与一个阈

Java数据处理之中值滤波算法_不想换名了的博客-程序员宅基地

一般而言,对于硬件收集来的各种数据都是要进行滤波的,滤波的手法有很多种,只是一般都不会在java层进行。但是也有一些特别小巧实用易懂的方法,可以用来对数据进行滤波,譬如中值滤波算法。  该算法在波形类数据中经常会用上,主要效果是突出特征波形,使得波形更加”凹凸有致“。但是也有一定副作用,那就是如果波形本身就非常漂亮,那就有可能将其特征波形稍稍磨平——当然这种效果基本还是在能接受范围内。

HDU2072 单词数 解题报告--set_夕里子的博客-程序员宅基地

单词数Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22195    Accepted Submission(s): 5379Problem Descriptionlily的好朋友xiaoou333最近很空,他想了

【Rust日报】2021-03-03 -- Pycharm 也可以调试 Rust 啦!_Rust语言中文社区的博客-程序员宅基地

Qovery Engine- Rust库,可在云服务上自动化部署应用程序Qovery Engine是一个开源抽象层库,仅需几分钟,它就可以轻松地在AWS,GCP,Azure和其他云提供商...

java程序员第四课 javaScript基础和DOM目录_Cb_MX的博客-程序员宅基地

1、内容回顾2、Element对象 * 如果要操作元素(标签),首先要获取到元素 - document里面的三个方法 ** 获取属性值 - getAttribute(“属性名称”) - var input1 = document.getElementById(“id1”); //alert(input1.value)

随便推点

求n的阶乘后有多少个0_pardon110的博客-程序员宅基地

需求n!后面有多少个06!=12345*6=720.720后面有1个0n=10000,求n!。解析因2足够多,简化为每个阶,多少个5的因子,每个记一次0顺序排序n个数,每轮除5,得到累计5的指数(5,25,125…)的个数,后累加js解法n=0 // 计数k=10000 // 初始值// 外层遍历阶数for(k;k&amp;amp;amp;amp;amp;amp;gt;=1;k--){ ...

GitHub报错master->master(fetch first)_努力的老周的博客-程序员宅基地

刚才在GitHub上建立了一个代码仓库,想吧以前写的一些代码上传到服务器,执行git push -u origin master后出现以下错误。$ git push -u origin masterTo https://github.com/justidle2012/PATSolution.git! [rejected] master -&gt; master (fetch...

Test1_不如不见_莎的博客-程序员宅基地_starters1test1

Test标题内容第二段内容下面展示一些 内联代码片。// A code blockvar foo = 'bar';// An highlighted blockvar bar=jjj;

SPOJ 4491PGCD_DDY92的博客-程序员宅基地

这是GCD八题中最难的一题,自己写的是各种超时,只好参考网上大牛的解题报告,研究了一上午,终于给搞懂了.....题目要求:gcd(i,j)=素数的对数,其中1对于求解gcd(i,j)=k的对数利用莫比乌斯反演我们已经可以求解,所以最单纯的想法便是枚举素数然后逐个求解,这样肯定会TLE的。采取了网上一大牛的思路:我们要求解的结果为 Sigma(p, Sigma(p|d, mu

Runtime 控制UIButton的暴力点击_iOSmling的博客-程序员宅基地

大体上就是把 UIControl  category  把点击事件 同时指定到自己的方法里面 让每一个button都执行#import @interface UIControl (Interval)@property (nonatomic, assign) NSTimeInterval cjr_acceptEventInterval;// 可以用这个给重复点击加间隔

git服务器搭建_程序猿来是你的博客-程序员宅基地_腾讯云搭建git 服务器ubuntu

git服务器搭建http://blog.chinaunix.net/uid-26611973-id-3373977.html分类: LINUX2012-10-15 16:58:15 硬件需求:一台linux Ubuntu电脑(虚拟机),在公司局域网内有独立IP,并且保证小组每个人都能ping通;软件需求:git-core, gitosis, openssh-server, o...

推荐文章

热门文章

相关标签