美文网首页
Javascript学习笔记-AJAX

Javascript学习笔记-AJAX

作者: 阳明先生1208 | 来源:发表于2016-09-22 11:14 被阅读16次

    AJAX即Asynchronous JavaScript and XML,意思就是用JS异步网络请求,也就是通过回调函数获得数据。AJAX请求数据主要依靠XMLHttpRequest对象, 而低版本的IE依靠的是ActiveXObject对象:

    function success(text) {
        var textarea = document.getElementById('test-response-text');
        textarea.value = text;
    }
    
    function fail(code) {
        var textarea = document.getElementById('test-response-text');
        textarea.value = 'Error code: ' + code;
    }
    
    var request;
    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();
    } else {
        request = new ActiveXObject('Microsoft.XMLHTTP');
    }
    request.onreadystatechange = function () { // 状态发生变化时,函数被回调
        if (request.readyState === 4) { // 成功完成
            // 判断响应结果:
            if (request.status === 200) {
                // 成功,通过responseText拿到响应的文本:
                return success(request.responseText);
            } else {
                // 失败,根据响应码判断失败原因:
                return fail(request.status);
            }
        } else {
            // HTTP请求还在继续...
        }
    }
    // 发送请求:
    request.open('GET', '/api/categories');
    request.send();
    

    通过检测window对象是否有XMLHttpRequest属性来确定浏览器是否支持标准的XMLHttpRequest,不要根据浏览器的navigator.userAgent来检测浏览器是否支持某个JS特性,一是因为这个字符串本身可以伪造,二是通过IE版本判断JS特性没有确定性。

    XMLHttpRequest对象的open()方法有3个参数,第一个参数指定请求方式,第二个参数指定URL地址,第三个参数指定同步还是异步,默认是true,千万不要设为false,这里一般不写。最后调用send()方法发送请求,GET请求不需要参数,POST请求需要把body部分以字符串或者FormData对象传进去。

    JSONP

    AJAX请求指定的URL必须和当前页面完全一致,这是因为浏览器的同源策略规定的,就是域名、协议、端口号都要要相同。

    那么如何用JS请求外域(就是其他网站)的URL呢?方法有以下几种:

    1. 通过Flash插件发送HTTP请求,这种方式可以绕过浏览器的安全限制,但必须安装Flash,而且Flash用起来麻烦,所以现在用得也越来越少了。
    2. 通过在同源域名下架设一个代理服务器来转发,JS负责把请求发送到代理服务器:/proxy?url=http://www.sina.com.cn,代理服务器再把结果返回,这样就遵守了浏览器的同源策略,但这种方式需要额外的服务器做开发。
    3. 利用浏览器允许跨域引用JS资源即JSONP,但它限制只能用GET请求,并且要求返回JS。JSONP通常以函数调用的形式返回,先准备好调用的函数,然后给页面动态加一个<script>节点,相当于动态读取外域的JS资源。
    以163的股票查询URL为例,对于URL:http://api.money.126.net/data/feed/0000001,1399001?callback=refreshPrice
    
    refreshPrice({"0000001":{"code": "0000001", ... });
    // 回调函数:
    function refreshPrice(data) {
        var p = document.getElementById('test-jsonp');
        p.innerHTML = '当前价格:' +
            data['0000001'].name +': ' + 
            data['0000001'].price + ';' +
            data['1399001'].name + ': ' +
            data['1399001'].price;
    }
    function getPrice() {
        var js = document.createElement('script'),
            head = document.getElementsByTagName('head')[0];
        js.src = 'http://api.money.126.net/data/feed/0000001,1399001?callback=refreshPrice';
        head.appendChild(js);
    }
    
    CORS

    HTML5推出了新的跨域策略CORS,全称Cross-Origin Resource Sharing:Origin表示浏览器当前页面域,当JS向外域发起请求浏览器收到响应后,首先检查Access-Control-Allow-Origin是否包含本域,如果包含则此次跨域请求成功,如果不包含则请求失败。
    假设本域是my.com,外域是sina.com,只要响应头Access-Control-Allow-Origin为http://my.com或者是*,本次请求就可以成功。可见,跨域能否成功取决于对方服务器是否愿意给你设置一个正确的Access-Control-Allow-Origin,决定权始终在对方手中。这种跨域请求称之为“简单请求”,它包括GET、HEAD和POST(POST的Content-Type类型仅限application/x-www-form-urlencoded、multipart/form-data和text/plain),并且不能出现任何自定义头(例如,X-Custom: 12345),通常能满足基本需求。

    目前主流的浏览器都支持HTML5,在引用外域资源时都要验证CORS。例如引用第三方字体文件:

    /* CSS */
    @font-face {
      font-family: 'FontAwesome';
      src: url('http://cdn.com/fonts/fontawesome.ttf') format('truetype');
    }
    // 如果该CDN服务商未正确设置Access-Control-Allow-Origin,那么浏览器无法加载字体资源。
    

    对于PUT、DELETE以及其他类型如application/json的POST请求,在发送AJAX请求之前,浏览器会先发送一个OPTIONS请求(称为preflighted请求)到这个URL上,询问目标服务器是否接受:

    OPTIONS /path/to/resource HTTP/1.1
    Host: bar.com
    Origin: http://my.com
    Access-Control-Request-Method: POST
    

    服务器必须响应并明确指出允许的Method:

    HTTP/1.1 200 OK
    Access-Control-Allow-Origin: http://my.com
    Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS
    Access-Control-Max-Age: 86400
    浏览器确认服务器响应的Access-Control-Allow-Methods头确实包含将要发送的AJAX请求的Method,才会继续发送AJAX,否则,抛出一个错误。
    

    由于以POST、PUT方式传送JSON格式的数据在REST中很常见,所以要跨域正确处理POST和PUT请求,服务器端必须正确响应OPTIONS请求。

    相关文章

      网友评论

          本文标题:Javascript学习笔记-AJAX

          本文链接:https://www.haomeiwen.com/subject/ommaettx.html