原生的AJAX——0624笔记整理

原生ajax相关内容,同步异步,cros跨域,jsonp跨域。

一、什么是AJAX

AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。(局部刷新技术)

  • AJAX 和请求数据有关。
  • AJAX = 异步 JavaScript 和 XML(XML也是一种树形结构文档,写法和html写法一致,写的标签是自定义的标签)。
  • 是一种用于创建快速动态网页的技术。
  • AJAX 通过在后台与服务器进行少量数据交换,返回到前端,使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
  • 传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

二、五步法书写原生ajax

1、创建XMLHttpRequest对象( 考虑 ie5 ie6的兼容)

2、使用open 方法建立连接

参数:
(1)method——请求的方式(get 、post)
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
但是在以下情况中,请使用 POST 请求:

无法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

(2)url——文件在服务器上的地址
该文件可以是任何类型的文件,比如 .txt 和 .xml,或者服务器脚本文件,比如 .asp 和 .php (在传回响应之前,能够在服务器上执行任务)。
注意:
如果请求方式为get,并且URL里边只写文件地址的话,那么可能得到的是缓存的结果,为了避免浏览器缓存,可以向URL 添加一个唯一的id,如:

xmlhttp.open("GET","/try/ajax/demo_get.php?t=" + Math.random(),true);

post方式就不需要考虑这个问题。

(3)async——ajax 请求是异步还是同步( 默认是异步,true 异步 false 同步)

异步就是:在等待服务器响应时执行其他脚本,当响应就绪后对响应进行处理。

XMLHttpRequest 对象如果要用于 AJAX 的话,其 open() 方法的 async 参数必须设置为 true。
原生js不能使用同步,因为ajax对象在主线程。

当使用 async=true 时,需要规定在响应处于 onreadystatechange 事件中的就绪状态时执行的函数;
当使用 async=false 时,不要编写 onreadystatechange 函数 - 把代码放到 send() 语句后面即可。

一般不推荐使用 async=false,但是对于一些小型的请求,也是可以的。
需要注意的是,JavaScript 会等到服务器响应就绪才继续执行。如果服务器繁忙或缓慢,应用程序会挂起或停止。

(4)用户名(指的是服务器的用户名和密码)
(5)密码

3、使用send 方法发送请求

如果需要像 HTML 表单那样传递数据:

请求方式为get,传递的数据直接写在 url 路径之后,如:

xmlhttp.open("GET","http://www.maodou.com/getdata?id=10086&pwd=12345",true);
send();

请求方式为post,需要使用 setRequestHeader() 来添加 HTTP 头,然后将传递的数据写在 send 方法里面,如:

xmlhttp.open("POST","/try/ajax/demo_post2.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
send("fname=Henry&lname=Ford");

注意:setRequestHeader() 要写在open之后,send之前。

4、ajax响应事件

当请求被发送到服务器时,我们需要执行一些基于响应的任务。
当 readyState 等于 4 且状态为 200 时,表示响应已就绪:

readyState 属性存有 XMLHttpRequest 的状态信息,从 0 到 4 发生变化。

0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪

每当 readyState 改变时,就会触发 onreadystatechange 事件。
(onreadystatechange 事件被触发 4 次(0 - 4), 分别是: 0-1、1-2、2-3、3-4,对应着 readyState 的每个变化。)

status

200-服务器响应成功
404-页面丢失
500-服务器报错

5、页面更新

如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。
response 获得object形式的响应数据。
responseText:获得string形式的响应数据。
responseXML:获得 XML 形式的响应数据。

完整代码如下:

<script>
    //1.创建ajax对象
    var xmlHttp;
    if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
    else {
        //考虑ie5 ie6 兼容性
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    //2.建立连接
    xmlHttp.open("get", "", true);
    //3.发送请求
    xmlHttp.send();
    //4.响应事件
    xmlHttp.onreadystatechange = function () {
        //readyState==4  读取完成
        //status==200 服务器响应成功  404 页面丢失   500 服务器报错
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
            //5.获取服务器响应数据
            //下面两个都是服务器响应数据
            xmlHttp.response;  //object
            xmlHttp.responseText;  //string
            //拿到数据 操作dom 更新界面
        }
    }
</script>

三、原生ajax 的封装

<script>
    //ajax封装  根据请求方式 和 是否传给服务器递数据data进行判断
    function ajax(method, url, data, callback) {
        var xmlHttp;
        //做兼容处理
        if (window.XMLHttpRequest) {
            xmlHttp = new XMLHttpRequest();
        }
        else {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        if (method == "get") {
            if (data) {
                url += "?";
                url += data;
            }
            xmlHttp.open(method, url, true);
            xmlHttp.send();
        }
        else {
            xmlHttp.open(method, url, true);
            //设置响应头
            xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            if (data) {
                xmlHttp.send(data);
            }
            else {
                xmlHttp.send();
            }
        }
        xmlHttp.onreadystatechange = function () {
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                callback(xmlHttp.response);
            }
        }
    }
    
    //使用的时候直接调方法
    //这里使用了回调函数  使得后端返回的数据xmlHttp.response可以在外边使用
    ajax("get", "./data/stu.json", null, function (res) {
        console.log(res);
    })
</script>

注意:
如果需要发送数据,data 必须为以下格式:

var data = "id=10086&name=张三&sex=男";

四、ajax 跨域问题

1、ajax请求出现跨域错误的原因

ajax出现请求跨域错误问题,主要原因就是因为同源政策规定,AJAX请求只能发给同源的网址,否则就报错。即:

  1. 协议相同
  2. 域名相同
  3. 端口相同

如果非“同源”,共有三种行为受到限制:

  1. Cookie、LocalStorage 和 IndexDB 无法读取。
  2. DOM 无法获得。
  3. AJAX 请求不能发送。

虽然这些限制是必要的,但是有时很不方便,合理的用途也受到影响。下边是 AJAX 请求不能发送 时的解决方案。其它两种情况的解决方案参考:
浏览器同源政策及其规避方法——阮一峰

2、ajax跨域的表现

参考ajax跨域的表现

3、ajax请求出现跨域错误的解决方案

(1)CROS方式

直接去后端设置 header(头信息) Access-Control-Allow-Origin: * 允许所有域名访问。
Access-Control-Allow-Origin这个字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

更多关于CROS的问题,可以参考:
跨域资源共享CROS详解——阮一峰

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
相比JSONP只能发GET请求,CORS允许任何类型的请求。

(2)JSONP方式

JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。
缺点:只能发送GET请求。

它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

  1. JSONP 跨域是通过前端src 访问后端接口,传递参数以及回调函数(因为在前端,src属性可以直接连接远程的api(程序应用集,也叫接口));
  2. 后端接收回调函数,返回回调函数的执行(携带实参)到前端——把数据通过实参的形式传递给前端;
  3. 前端的函数执行,获取服务器响应。

写法:

    <script>
        function getData(res) {
            console.log(res);
        }
    </script>
    <script src="http://jia.maodou.com:8000/addinfo?id=10086&name=张三&callback=getData"></script>

注意:先定义函数,再调用API接口。

3、document.domain + iframe跨域

使用该方案的前提:
这两个域名必须属于同一个一级域名。而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域。

举例:
news.baidu.com里的一个网页(news.html)引入了map.baidu.com里的一个网页(map.html
这时news.html里是不能操作map.html里面的内容的。
因为document.domain不一样,一个是news.baidu.com,另一个是map.baidu.com
这时我们就可以通过Javascript,对两个域名进行降级处理,即将两个页面的domain改成一样的,
需要在a.html里与b.html里都加入:

document.domain = “baidu.com”;

代码如下:
news.baidu.com下的news.html页面:

<script>
    document.domain = 'baidu.com';
    var ifr = document.createElement('iframe');
    ifr.src = 'map.baidu.com/map.html';
    ifr.style.display = 'none';
    document.body.appendChild(ifr);
    ifr.onload = function(){
        var doc = ifr.contentDocument || ifr.contentWindow.document;
        // 这里可以操作map.baidu.com下的map.html页面
        var oUl = doc.getElementById('ul1');
        alert(oUl.innerHTML);
        ifr.onload = null;
    };
</script>

map.baidu.com下的map.html页面:

<ul id="ul1">我是map.baidu.com中的ul</ul>
<script>
    document.domain = 'baidu.com';
</script>

详细内容参考:
通过 document.domain + iframe 解决跨域问题——猫老板的豆

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值