美文网首页JavaScript 从零开始程序员
[JavaScript] (Day-20) - AJAX 简介

[JavaScript] (Day-20) - AJAX 简介

作者: 已重置2020 | 来源:发表于2017-07-11 22:55 被阅读25次
    Love me little and love me long. 不求情意浓,但愿情义长。

    AJAX 不是 JavaScript 的规范,而是用 JavaScript 执行异步网络请求,缩写为:Asynchronous JavaScript and XML

    JavaScript 的一个重要的特性就是单线程执行模式

    AJAX 请求是异步执行的,所以 JavaScript 通过 AJAX 回调函数获得响应

    Web的运作原理:一次 HTTP 请求对应一个页面, 所以要想同一个界面请求不同数据,必须使用异步执行操作

    在现代浏览器上写 AJAX 主要依靠XMLHttpRequest对象:

    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 = new XMLHttpRequest(); // 新建XMLHttpRequest对象
    
    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();
    
    alert('请求已发送,请等待响应...');
    
    
    解释:

    XMLHttpRequest对象的open()方法有3个参数,第一个参数指定是GET还是POST,第二个参数指定URL地址,第三个参数指定是否使用异步,默认是true,所以不用写

    注意,千万不要把第三个参数指定为false,否则浏览器将停止响应,直到AJAX请求完成。如果这个请求耗时10秒,那么10秒内你会发现浏览器处于“假死”状态

    最后调用send()方法才真正发送请求。GET请求不需要参数,POST请求需要把body部分以字符串或者FormData对象传进去


    安全限制

    上面代码的URL使用的是相对路径。如果你把它改为'http://www.sina.com.cn/',再运行,肯定报错

    是因为浏览器的同源策略导致的。默认情况下,JavaScript在发送AJAX请求时,URL的域名必须和当前页面完全一致

    完全一致的意思是,域名要相同(www.example.com和example.com不同),协议要相同(http和https不同),端口号要相同(默认是:80端口,它和:8080就不同)。有的浏览器口子松一点,允许端口不同,大多数浏览器都会严格遵守这个限制。

    那怎么用JavaScript请求外域(就是其他网站)的URL?

    方法一:

    一是通过Flash插件发送HTTP请求,这种方式可以绕过浏览器的安全限制,但必须安装Flash,并且跟Flash交互。不过Flash用起来麻烦,而且现在用得也越来越少了


    方法二:

    二是通过在同源域名下架设一个代理服务器来转发,JavaScript负责把请求发送到代理服务器:

    '/proxy?url=http://www.sina.com.cn'
    

    代理服务器再把结果返回,这样就遵守了浏览器的同源策略。这种方式麻烦之处在于需要服务器端额外做开发。


    方法三

    第三种方式称为JSONP,它有个限制,只能用GET请求,并且要求返回JavaScript。这种方式跨域实际上是利用了浏览器允许跨域引用JavaScript资源

    JSONP一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了

    <html>
        <head>
            <meta charset="utf-8" />
            <title>学习JSONP</title>
            
            <script src="http://example.com/abc.js"></script>
            
            <script>
                function refreshPrice(data) {
                    var p = document.getElementById('test-jsonp');
                    p.innerHTML = '当前价格:' +
                    data['0000001'].name +':' + 
                    data['0000001'].price + ';' +
                    data['1399001'].name + ':' +
                    data['1399001'].price;
                }
            </script>
            <script>
                function getPrice() {
                    var js = document.createElement('script');
                    var head = document.getElementsByTagName('head')[0];
                    js.src = 'http://api.money.126.net/data/feed/0000001,1399001?callback=refreshPrice';
                    head.appendChild(js);
                }
            </script>
        </head>
        <body>  
                <p id='test-jsonp'>当前价格:</p>
                <button type="button" onclick="getPrice()">刷新</button>
        </body>
    </html>
    
    解释:
    1. 方法 getPrice()中 创建了一个 script 元素
    2. 并给script元素 添加引用js.src, 关键代码在 src 中的 callback=refreshPrice
    3. 给创建head 便签,并将script添加为子元素
    4. 通过 button 的点击事件,触发 getPrice()
    5. getPrice() 中的js.src获取到回调方法 refreshPrice() 并异步执行,并回调请求结果
    6. refreshPrice()方法获取到数据进行展示

    相关文章

      网友评论

        本文标题:[JavaScript] (Day-20) - AJAX 简介

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