Ajax-跨域
来源:互联网 发布:java解析syslog 编辑:程序博客网 时间:2024/06/05 16:33
一个域名地址的组成:
浏览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。当协议、子域名、主域名、端口号中任意一个不同时,都算做不同域,不同域之间相互请求资源,就算做“跨域”。
跨域解决方法:
1、代理(后台解决);
2、JSONP(针对 GET 方式);
3、XHR2(IE10以下不支持)。
JSONP
Jsonp原理:
首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 json 数据。然后以 javascript 语法的方式,生成一个function,function 名字就是传递上来的callback的名字。最后将事先生成的 json 数据直接以参数的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。客户端浏览器解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里。
JSONP实例:百度搜索
<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> *{ margin: 0; padding: 0;} #q{ display: block; width: 300px; height: 30px; border: 1px solid #e1e1e1; margin: 50px auto 0;} #ul1{ list-style: none; width: 300px; border: 1px solid #EDEDED; margin: -1px auto 0; display: none;} #ul1 li a{ display: block; height: 30px; line-height: 30px; padding: 0 5px; text-decoration: none; color: #666;} #ul1 li a:hover{ background: #ededed;} </style> <script type="text/javascript"> function jsonpCallback(data){ var oUl=document.getElementById("ul1"); var html=''; if (data.s.length) { oUl.style.display='block'; for (var i=0; i<data.s.length; i++) { html+='<li><a target="_blank" href="https://www.baidu.com/s?wd='+ data.s[i] +'">'+ data.s[i] +'</a></li>'; } oUl.innerHTML=html; }else{ oUl.style.display='none'; } } window.onload=function(){ var oQ=document.getElementById("q"); var oUl=document.getElementById("ul1"); oQ.onkeyup=function(){ if (this.value!='') { var oScript=document.createElement('script'); oScript.src='https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?json=1&cb=jsonpCallback&wd='+this.value; document.body.appendChild(oScript); }else{ oUl.style.display='none'; } } document.onclick=function(){ oUl.style.display='none'; } } </script> </head> <body> <input id="q" type="text" /> <ul id="ul1"> <!--<li><a target="_blank" href="#">11</a></li> <li><a target="_blank" href="#">22</a></li> <li><a target="_blank" href="#">33</a></li>--> </ul> </body></html>
JSONP并不是所有跨域通信需求的万灵药,它有一些缺陷。
第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到 404 错误,也不能取消或重新开始请求。
JSONP 的另一个主要缺陷是被不信任的服务使用时会很危险。因为 JSONP 服务返回打包在函数调用中的 JSON 响应,而函数调用是由浏览器执行的,这使宿主 Web 应用程序更容易受到各类攻击。
JQ应用JSONP的实例:上文中的案例,当把GET方法中请求的url由”http://localhost/ajaxdemo/server.php“改为”http://127.0.0.1/ajaxdemo/server.php“之后,就出现了跨域问题。
解决之后的前端代码:
<script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.js"></script><script>$(document).ready(function(){ $('#search').click(function(){ $.ajax({ type:"GET", url:"http://127.0.0.1/ajaxdemo/server.php?number=" + $('#keyword').val()+"&"+ Math.random(), dataType:'jsonp', jsonp:'callback', success:function(data){ if (data.success) { $('#searchResult').html(data.msg); }else{ $('#searchResult').html('出了错误:'+data.msg); } }, error:function(jqXHR){ alert("发生错误:" + jqXHR.status); } }); })})</script>
可以看出前端代码仅修改增加了以下代码字段:
dataType:'jsonp',jsonp:'callback',
服务端代码修改后为:
<?phpheader("Content-Type: application/json;charset=utf-8"); $staff = array ( array("name" => "洪七", "number" => "101", "sex" => "男", "job" => "总经理"), array("name" => "郭靖", "number" => "102", "sex" => "男", "job" => "开发工程师"), array("name" => "黄蓉", "number" => "103", "sex" => "女", "job" => "产品经理") );if ($_SERVER["REQUEST_METHOD"] == "GET") { search();} elseif ($_SERVER["REQUEST_METHOD"] == "POST"){ create();}function search(){ $jsonp=$_GET["callback"]; if (!isset($_GET["number"]) || empty($_GET["number"])) { echo $jsonp.'({"success":false,"msg":"参数错误"})'; return; } global $staff; $number = $_GET["number"]; $result = '{"success":false,"msg":"没有找到员工"}'; foreach ($staff as $value) { if ($value["number"] == $number) { $result = $jsonp.'({"success":true,"msg":"找到员工:员工编号:' . $value["number"] . ',员工姓名:' . $value["name"] . ',员工性别:' . $value["sex"] . ',员工职位:' . $value["job"] . '"})'; break; } } echo $result;}?>
XHR2
HTML5中提供的XMLHttpRequest Level2(即XHR2)已经实现了跨域访问。但ie10以下不支持。
只需要在服务端填上以下响应头:
header("Access-Control-Allow-Origin:*");/*星号表示所有的域都可以接受,*/header("Access-Control-Allow-Methods:GET,POST");
总结:代理实现最麻烦,但使用最广泛,任何支持AJAX的浏览器都可以使用这种方式。JSONP相对简单,但只支持GET方式调用。XHR2最简单,但只支持HTML5,如果是移动端开发,可以选择使用XHR2。
- AJAX跨域
- ajax跨域
- ajax 跨域
- ajax跨域
- AJAX跨域
- ajax跨域
- ajax跨域
- ajax跨域
- Ajax跨域
- ajax 跨域
- ajax跨域
- Ajax跨域
- ajax跨域
- ajax跨域
- AJAX跨域
- ajax跨域
- ajax跨域
- Ajax跨域
- spring mvc @ResponseBody 返回中文乱码
- 解析shiny程序
- Libgdx之游戏源码合集
- html001-标题
- 字母游戏
- Ajax-跨域
- 中间件的发展
- hadoop中NameNode、DataNode、SecondaryNameNode、JobTracker 、TaskTracker介绍
- 德式时间管理
- NNU_20161027_2P81
- blue
- cookie的作用和弊端
- 猜素数游戏
- Xcode7 导入pch 文件报错