ajax 跨域

本文详细介绍了跨域的概念、出现跨域的原因及三种处理方法:代理、JSONP和XHR2,帮助开发者解决实际工作中的跨域问题。

一.什么是跨域


域名地址的组成:
http:// www . abc.com : 8080 / script/jquery.js
http:// (协议号) www (子域名) abc.com (主域名) 8080 (端口号) script/jquery.js (请求的地址)

当协议、子域名、主域名、端口号中任意一个不相同时,都算不同的“域”。
不同的域之间相互请求资源,就叫“跨域”。
比如:http://www.abc.com/index.html 请求 http://www.def.com/sever.php

二.出现跨域的情况

由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问。
比如说你的网站域名是aaa.com,想要通过AJAX请求bbb.com域名中的内容,浏览器就会认为是不安全的,所以拒绝访问。
会出现跨域的情况

编号URL说明
1http://www.aaa.com/index.html
http://www.aaa.com/a.js
同域名,非跨域
2http://www.abc.com/index.html
http://www.efg.com/service.php
主域名不同,跨域
3http://www.abc.com/index.html
http://bbs.abc.com/service.php
子域名不同,跨域
4http://www.abc.com/index.html
http://www.abc.com:8080/service.php
端口号不同,跨域
5http://www.abc.com/index.html
https://www.abc.com/service.php
协议不同,跨域

三.处理跨域的方法一:代理

这种方式是通过后台(ASP、PHP、JAVA、ASP.NET)获取其他域名下的内容,然后再把获得内容返回到前端,这样因为在同一个域名下,所以就不会出现跨域的问题。

  • 通过在同域名的web服务器端创建一个代理:
  • 北京服务器(域名:www.beijing.com)
    上海服务器(域名:www.shanghai.com)
  • 比如在北京web服务器的的后端(www.beijing.com/sever.php)直接访问上海的服务,然后把获取的响应值返回给前端。也就是北京的服务在后台做了一个代理,前端只需要访问北京的服务器也就相当与访问了上海的服务器。这种代理属于后台的技术,所以不展开叙述。

四.处理跨域的方法二:JSONP

在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。

假设在 http://www.aaa.com/index.php 这个页面中向http://www.bbb.com/getinfo.php提交GET请求,那么我们在www.aaa.com页面中添加如下代码:

<script>
    var eleScript= document.createElement("script"); //创建一个script元素
    eleScript.type = "text/javascript"; //声明类型、
    eleScript.src = "http://www.bbb.com/getinfo.php"; //添加src属性 引入跨域访问的url
    document.getElementsByTagName("HEAD")[0].appendChild(eleScript); //在页面中添加新创建的script元素
</script>

当GET请求从http://www.bbb.com/getinfo.php返回时,可以返回一段JavaScript代码,这段代码会自动执行,可以用来负责调用http://www.aaa.com/index.php页面中的一个callback函数。看下面一个列子:
在www.aaa.com页面中:

<script>
  function jsonp( json ){
    document.write( json.name ); //输出周星驰
}
<script>
<script src="http://www.bbb.com/getinfo.php"></script>

在www.bbb.com页面中:

jsonp({ "name":"周星驰","age":45 });

也就是在www.aaa.com页面中声明,在www.bbb.com页面中调用。但是JSONP只支持 “GET” 请求,但不支持 “POST” 请求。

jsonp的原理:

  • ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
  • 定义函数
  • src包含外部文件(被包含的外部文件可以是任何类型的文件),它只关注被包含的外部文件的内容是否是合法的JS,在被包含的文件中执行调用定义好的函数。
  • 参数(数据)的实现
  • 问题:包含就调用,通过动态创建<script>实现按需调用
  • 问题:包含动态文件时可以通过一个接口实现按需生成调用函数名称
  • 在资源加载进来之前定义好一个函数,这个函数接收一个参数(数据),函数里面利用这个参数做一些事情, 然后需要的时候通过script标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,就会去执行我们前面定义好的函数,并且把数据当作这个函数的参数传入进去。

案例:
百度搜索提升框:打开百度,我们一边打字会发现出现相关的关键字供你查看:这个时候打开网络查看,发现这个数据是通过ajax的方式动态加载过来的,还能找到这个域名请求的地址:

<!DOCTYPE html>
<html>
    <head id="head">
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            body{padding: 50px;}
            *{
                margin: 0;
                padding: 0;
            }
            li{
                list-style: none;
                height: 30px;
                line-height: 30px;
            }
            #txt{
                width: 300px;
                height: 40px;
            }
            ul{
                width: 300px;
                border: 1px solid #D8D8D8;
                display: none;
            }
            ul li a{
                display: block;
                text-decoration: none;
                color: #000000;
                padding-left: 10px;
            }
            ul li a:hover{
                background: #D8D8D8;
            }
        </style>
        <script>
            function fn(data){
                var oUl = document.getElementById('list');
//              console.log(data);
                var html = '';
                var arr = data.s;
                for(var i=0;i<arr.length;i++){
                    html += '<li><a href="https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd='+arr[i]+'" target="_blank">'+arr[i]+'</a></li>'
                }
                oUl.innerHTML = html;
            }
        </script>
        <script>
            window.onload = function(){
                var oTxt = document.getElementById('txt');
                var oUl = document.getElementById('list');
                var oHead = document.getElementById('head');
                oTxt.onkeyup = function(){
                    if(oTxt.value != 0){
                        var oS = document.createElement('script');
                        oS.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd='+oTxt.value+'&cb=fn';
                        oHead.appendChild(oS);
                        oUl.style.display = 'block';
                    }
                    else{
                        oUl.style.display = 'none';
                    }   
                }
            }
        </script>
    </head>
    <body>
        <input type="text" id="txt" />
        <ul id="list">

        </ul>
    </body>
</html>

效果:
这里写图片描述

五.处理跨域的方法三:XHR2

“XHR2” 全称 “XMLHttpRequest Level2” 是HTML5提供的方法,对跨域访问提供了很好的支持,并且还有一些新的功能。

  • IE10以下的版本都不支持

  • 只需要在服务器端头部加上下面两句代码:

header( “Access-Control-Allow-Origin:*” );

header( “Access-Control-Allow-Methods:POST,GET” );

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值