实现跨域网络访问

实现跨域网络访问

基本说明

在前端开发中,我们可以使用ajax来发送网络请求。
发送请求的方式:GET请求|POST请求
发送请求的主要步骤:
GET请求:
    1)创建请求对象(XMLHTTPRequest)注意兼容性问题
    2)设置请求方法和路径(open方法)
    3)发送请求(send方法)
    4)监听网络请求的状态(onreadystateschange)
    5)处理服务器返回的数据(先判断请求是否成功再解析)
    注意点:参数拼接在请求路径的后面,放在url中传递,因为部分浏览器对URL的长度和大小有限制,因此不能黑夜GET请求发送较大的数据,且安全性较差。

POST请求:
    1)创建请求对象(XMLHTTPRequest)注意兼容性问题
    2)设置请求方法和路径(open方法)
    3)设置请求头部信息(setRequestHeader)
    4)发送请求(send方法,参数放在该方法中传递)
    5)监听网络请求的状态(onreadystateschange)
    6)处理服务器返回的数据(先判断请求是否成功再解析)
    注意点:注意设置请求头的位置(应该在open方法和send方法中间),参数以固定的格式放在send方法中传递,相对安全。

Ajax补充说明

01 基本说明
    Ajax全称Asynchronous JavaScript and XML,也就是异步的JavaScript和XML,它本身不是单一技术,是一些技术的集合,主要有:
    001.JavaScript,通过用户或其他与浏览器相关事件捕获交互行为
    002.XMLHttpRequest对象,通过这个对象可以在不中断其它浏览器任务的情况下向服务器发送请求;
    003.服务器上的文件,以 XML、HTML 或 JSON 格式保存文本数据;

02 Ajax的优点
    001.不需要插件支持(只需要浏览器运行JavaScript 即可);
    002.更好的用户体验(发送请求获取数据可以不必更新整个页面);
    003.更好的性能(按照需求发送请求数据,不需要整体提交);
    004.减轻服务器和带宽的负担(将服务器的一些操作转移到客户端);

03 Ajax的不足
    001.部分浏览器有兼容性问题(比如 IE中对XMLHTTPRequest对象兼容性不好);
    002.前进、后退的功能被破坏(因为Ajax是局部刷新);
    003.搜索引擎的支持度不够
    004.开发调试工具缺乏
    005.Ajax无法实现跨域网络请求(即只能请求相同域[同一服务器]的数据,不能跨域请求)

跨域请求的实现原理

简单说明

01 Ajax不能实现跨域请求(不能跨服务器请求,比如我们自己的服务器不能请求百度网页,因为域不一样)
02 要实现跨域发送请求可以借助script标签来实现,因为这个标签中的src可以引入外部的文件。

实现原理

     
    

    代码说明:
        001 如果在页面中提供两个script标签,第一个标签中声明一个show函数
        002 该函数接收一个对象作为参数,函数的内容是打印传递的参数
        003 根据js的语法规则,在第二个script中我们可以直接调用show方法
        004 又因为script标签中的src属性允许我们把脚本的内容提取到一个单独的js文件中,而在HTML页面中只需要通过src导入即可
        005 因此,我们可以把show方法的调用写到一个单独的js文件中,然后导入
        006 例如:,作用是把show.js中的代码拷贝到标签中执行

核心实现

基于script标签和scr属性节点的特点,我们可以考虑在页面中利用此特性来实现跨域请求。
(1)在页面中提供第一个script标签,在该标签中声明函数(设置形参)
(2)提供第二个script标签,把需要跨域访问的路径设置为该标签的src
(3)在对应的路径中,返回固定格式的JSON数据【函数名称(对象)】
(4)在声明的函数中对形参进行处理(形参就是跨域请求返回的数据)

代码示例:

<script>
        // 数据处理方法
        function json2str(data) {
            data.t = Math.random();
            var arr = [];
            for(var key in data){
                arr.push(key+"="+data[key]);
            }
            // 不能直接将中文提交给服务器, 中文需要编码之后再提交
            return encodeURI(arr.join("&"));
        }
        /*
         url: 跨域访问的地址
         注意点: url不能写死, 否则没有复用性
         data: 参数
         注意点: 参数也不能写死
         */

        function jsonp(options) {
            var temp = document.querySelector("#jsonpScript");

            if(temp){
                document.body.removeChild(temp);
            }

            // 随机生成一个函数名称, 避免冲突
            var name = ("XMG_"+Math.random()).replace(".", "");

            // 指定回调函数名称(本地创建一个函数作为回调函数)
            window[name] = options.fn;
            // 指定回调函数的名称(告诉服务器跨域访问之后回调的函数名称)
            options.data[options.cbName] = name;

            // 格式化参数
            var str = json2str(options.data);
            // 创建一个script标签
            var oScript = document.createElement("script");

            oScript.setAttribute("id", "jsonpScript");
            // 设置script标签的src属性
            var url = options.url+"?"+str;
            oScript.setAttribute("src", url);
            // 注意点: 创建好了script标签, 如果没有添加到界面中, 是不会请求src
            document.body.appendChild(oScript);
        }
    script>
    <script>
        window.onload = function () {
            // 1.拿到输入框
            var oInput = document.querySelector("input");

            // 2.监听用户输入事件
            oInput.onkeyup = function () {
                // 获取用户输入的内容
                var text = oInput.value;
                // 跨域访问
                jsonp({
                        "url": "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su",
                        "data": {
                            "wd": text
                        },
                        "cbName": "cb",
                        "fn": function (obj) {
                            // 1.创建ul
                            var oUl = document.querySelector("ul") || document.createElement("ul");
                            oUl.innerHTML = "";
                            // 2.遍历对象创建li
                            var arr = obj.s;
                            for (var i = 0, len = arr.length; i < len; i++) {
                                // 创建li
                                var oLi = document.createElement("li");
                                oLi.innerHTML = arr[i];
                                // 将创建的li添加到ul中
                                oUl.appendChild(oLi);
                            }
                            // 3.将ul添加到body中
                            document.body.appendChild(oUl);
                        }
                    });
            }
        }
    script>

你可能感兴趣的:(跨域)