ajxa的跨域处理

1、什么是跨域

指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javacript施加的安全限制




2、怎么处理跨域

方法一:代理(后台做的)


指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javacript施加的安全限制
例如www.123.com/index.html需要调用www.456.com/server.php . 可以写一个接口www.123.com/server.php .由这个接口在后端去调用www.456.com/server.php 并且拿到返回值,然后在返回给index.html 。这就是一个代理的模式。相当于绕过了浏览器,自然就不存在跨域问题。


方法二:jsonp(重点,但是只支持get方式请求。不支持post方式。)
方法三:XHR2(了解即可)


jsonp原理和步骤:
   
   
  1. <script>标签
  2. src的作用 : 加载(包含指定的外部文件)
  3. 可以跨域包含
  4. 被包含的资源可以是任何类型的文件(可以是txt,php等)
  5. 他只关注被包含的文件的内容是否是合法的JS
  6. 原理
  7. 定义函数
  8. 包含外部文件,在被包含的文件中执行调用定义好的函数
  9. 参数的(数据)的实现
  10. 问题:包含就调用,通过动态创建<script>实现按需调用
  11. 问题:包含动态文件时可以通过一个接口实现按需生成调用函数名称

   
   
  1. JSONP : JSON with Padding
  2. 1.script标签
  3. 2.用script标签加载资源是没有跨域问题的
  4. 在资源加载进来之前定义好一个函数,这个函数接收一个参数(数据),函数里面利用这个参数做一些事情
  5. 然后需要的时候通过script标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,就会去执行我们前面定义好的函数,并且把数据当作这个函数的参数传入进去

普通的ajax请求只能拿本地的文件:这个例子是没有问题的。
   
   
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <script>
  7. window.onload = function() {
  8. var oBtn = document.getElementById('btn');
  9. oBtn.onclick = function() {
  10. var xhr = new XMLHttpRequest();
  11. xhr.onreadystatechange = function() {
  12. if (xhr.readyState == 4) {
  13. if ( xhr.status == 200 ) {
  14. alert( xhr.responseText );
  15. }
  16. }
  17. }
  18. xhr.open('get', '1.txt', true);
  19. xhr.send();
  20. }
  21. }
  22. </script>
  23. </head>
  24. <body>
  25. <input type="button" value="按钮" id="btn" />
  26. </body>
  27. </html>
但是还用这个方法获取远程的数据(豆瓣api: http://api.douban.com/book/subjects?q=javascript&alt=json&max-results=1 )就拿不到数据了,因为这个就是跨域:
    
    
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <script>
  7. window.onload = function() {
  8. //ajax跨域请求限制
  9. var oBtn = document.getElementById('btn');
  10. oBtn.onclick = function() {
  11. var xhr = new XMLHttpRequest();
  12. xhr.onreadystatechange = function() {
  13. if (xhr.readyState == 4) {
  14. if ( xhr.status == 200 ) {
  15. alert( xhr.responseText );
  16. }
  17. }
  18. }
  19. xhr.open('get', 'http://api.douban.com/book/subjects?q=javascript&alt=json&max-results=1', true);
  20. xhr.send();
  21. }
  22. }
  23. </script>
  24. </head>
  25. <body>
  26. <input type="button" value="按钮" id="btn" />
  27. XMLHttpRequest cannot load http://api.douban.com/book/subjects?q=javascript&alt=json&max-results=1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
  28. <p>
  29. 跨域:跨域名
  30. 一个域名下的文件去请求了和他不一样的域名下的资源文件,那么就会产生跨域请求
  31. </p>
  32. </body>
  33. </html>

那怎么办呢?联想一下:

以前我们想用jq里面的方法,只要链接一个地址,这个jq文件可以在本地,也可以在远程服务器下面。
   
   
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
  7. <script>
  8. </script>
  9. </head>
  10. <body>
  11. JSONP : JSON with Padding
  12. 1.script标签
  13. 2.用script标签加载资源是没有跨域问题的
  14. </body>
  15. </html>
利用这个方法,我们就用创建 script 节点的方式来链接外部资源
   
   
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <script>
  7. function fn(data) {
  8. alert(data);
  9. }
  10. </script>
  11. <script src="2.txt"></script>
  12. <script>
  13. //alert(a);
  14. </script>
  15. </head>
  16. <body>
  17. </body>
  18. </html>

外部准备一个2.txt文件:
   
   
  1. fn([1,2,3]);
发现我们可以拿到数据。
当然,这个数据是想点击的时候再使用,我们就动态加载标签即可:
   
   
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <script>
  7. function fn(data) {
  8. alert(data);
  9. }
  10. </script>
  11. <!--<script src="2.txt"></script>-->
  12. <script>
  13. window.onload = function() {
  14. var oBtn = document.getElementById('btn');
  15. oBtn.onclick = function() {
  16. //当按钮点击的时候再去加载远程资源,让他执行
  17. var oScript = document.createElement('script');
  18. oScript.src = '2.txt';
  19. document.body.appendChild(oScript);
  20. }
  21. }
  22. </script>
  23. </head>
  24. <body>
  25. <input type="button" id="btn" value="按钮" />
  26. JSONP : JSON with Padding
  27. 1.script标签
  28. 2.用script标签加载资源是没有跨域问题的
  29. 在资源加载进来之前定义好一个函数,这个函数接收一个参数(数据),函数里面利用这个参数做一些事情
  30. 然后需要的时候通过script标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,就会去执行我们前面定义好的函数,并且把数据当作这个函数的参数传入进去
  31. </body>
  32. </html>

我们可以再写一个php文件,传送数据:点击按钮,加载数据插入到li里面
   
   
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <script>
  7. function fn(data) {
  8. var oUl1 = document.getElementById('ul1');
  9. var html = '';
  10. for (var i=0; i<data.length; i++) {
  11. html += '<li>'+data[i]+'</li>';
  12. }
  13. oUl1.innerHTML = html;
  14. }
  15. </script>
  16. <script>
  17. window.onload = function() {
  18. var oBtn1 = document.getElementById('btn1');
  19. oBtn1.onclick = function() {
  20. var oScript = document.createElement('script');
  21. oScript.src = 'getData.php';
  22. document.body.appendChild(oScript);
  23. }
  24. }
  25. </script>
  26. </head>
  27. <body>
  28. <input type="button" id="btn1" value="按钮" />
  29. <ul id="ul1"></ul>
  30. </body>
  31. </html>
getData.php文件内容:


再一步完善:
   
   
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <script>
  7. function fn1(data) {
  8. var oUl1 = document.getElementById('ul1');
  9. var html = '';
  10. for (var i=0; i<data.length; i++) {
  11. html += '<li>'+data[i]+'</li>';
  12. }
  13. oUl1.innerHTML = html;
  14. }
  15. function fn2(data) {
  16. var oUl2 = document.getElementById('ul2');
  17. var html = '';
  18. for (var i=0; i<data.length; i++) {
  19. html += '<li>'+data[i]+'</li>';
  20. }
  21. oUl2.innerHTML = html;
  22. }
  23. function fn3(data) {
  24. var oUl3 = document.getElementById('ul3');
  25. var html = '';
  26. for (var i=0; i<data.length; i++) {
  27. html += '<li>'+data[i]+'</li>';
  28. }
  29. oUl3.innerHTML = html;
  30. }
  31. </script>
  32. <script>
  33. window.onload = function() {
  34. var oBtn1 = document.getElementById('btn1');
  35. var oBtn2 = document.getElementById('btn2');
  36. oBtn1.onclick = function() {
  37. var oScript = document.createElement('script');
  38. oScript.src = 'getData.php?callback=fn1';
  39. document.body.appendChild(oScript);
  40. }
  41. var oBtn2 = document.getElementById('btn2');
  42. oBtn2.onclick = function() {
  43. var oScript = document.createElement('script');
  44. oScript.src = 'getData.php?t=str&callback=fn2';
  45. document.body.appendChild(oScript);
  46. }
  47. var oBtn3 = document.getElementById('btn3');
  48. oBtn3.onclick = function() {
  49. var oScript = document.createElement('script');
  50. oScript.src = 'getData.php?callback=fn3';
  51. document.body.appendChild(oScript);
  52. }
  53. }
  54. </script>
  55. </head>
  56. <body>
  57. <input type="button" id="btn1" value="加载数字" />
  58. <ul id="ul1"></ul>
  59. <input type="button" id="btn2" value="加载字母" />
  60. <ul id="ul2"></ul>
  61. <input type="button" id="btn3" value="加载字母" />
  62. <ul id="ul3"></ul>
  63. </body>
  64. </html>
处理文件:
   
   
  1. <?php
  2. $t = isset($_GET['t']) ? $_GET['t'] : 'num';
  3. $callback = isset($_GET['callback']) ? $_GET['callback'] : 'fn1';
  4. $arr1 = array('111111','22222222','33333333','4444444','555555555555555555555');
  5. $arr2 = array('aaaaaaaaaaaa','bbbbbbbb','cccccccccccc','ddddddddd','eeeeeeeeeeee');
  6. if ($t == 'num') {
  7. $data = json_encode($arr1);
  8. } else {
  9. $data = json_encode($arr2);
  10. }
  11. echo $callback.'('.$data.');';

案例一:百度搜索提升框

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

   
   
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <style>
  7. #q {width: 300px; height: 30px; padding: 5px; border:1px solid #f90; font-size: 16px;}
  8. #ul1 {border:1px solid #f90; width: 310px; margin: 0;padding: 0; display: none;}
  9. li a { line-height: 30px; padding: 5px; text-decoration: none; color: black; display: block;}
  10. li a:hover{ background: #f90; color: white; }
  11. </style>
  12. <script>
  13. function fn(data) {
  14. var oUl = document.getElementById('ul1');
  15. var html = '';
  16. if (data.s.length) {
  17. oUl.style.display = 'block';
  18. for (var i=0; i<data.s.length; i++) {
  19. html += '<li><a target="_blank" href="http://www.baidu.com/s?wd='+data.s[i]+'">'+ data.s[i] +'</a></li>';
  20. }
  21. oUl.innerHTML = html;
  22. } else {
  23. oUl.style.display = 'none';
  24. }
  25. }
  26. window.onload = function() {
  27. var oQ = document.getElementById('q');
  28. var oUl = document.getElementById('ul1');
  29. oQ.onkeyup = function() {
  30. if ( this.value != '' ) {
  31. var oScript = document.createElement('script');
  32. oScript.src = 'http://suggestion.baidu.com/su?wd='+this.value+'&cb=fn';
  33. document.body.appendChild(oScript);
  34. } else {
  35. oUl.style.display = 'none';
  36. }
  37. }
  38. }
  39. </script>
  40. </head>
  41. <body>
  42. <input type="text" id="q" />
  43. <ul id="ul1"></ul>
  44. </body>
  45. </html>
效果:


案例二:豆瓣网查询书籍
   
   
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <style>
  7. #q {width: 300px; height: 30px; padding: 5px; border:1px solid #f90; font-size: 16px;}
  8. dl {border-bottom: 1px dotted #000;}
  9. dt {font-weight: bold;}
  10. </style>
  11. <script>
  12. function fn1(data) {
  13. var oMsg = document.getElementById('msg');
  14. var oList = document.getElementById('list');
  15. console.log(data);
  16. oMsg.innerHTML = data.title.$t + ' : ' + data['opensearch:totalResults'].$t;
  17. var aEntry = data.entry;
  18. var html = '';
  19. for (var i=0; i<aEntry.length; i++) {
  20. html += '<dl><dt>'+ aEntry[i].title.$t +'</dt><dd><img src="'+ aEntry[i].link[2]['@href'] +'" /></dd></dl>';
  21. }
  22. oList.innerHTML = html;
  23. }
  24. window.onload = function() {
  25. var oQ = document.getElementById('q');
  26. var oBtn = document.getElementById('btn');
  27. var oMsg = document.getElementById('msg');
  28. var oList = document.getElementById('list');
  29. oBtn.onclick = function() {
  30. if ( oQ.value != '' ) {
  31. var oScript = document.createElement('script');
  32. oScript.src = 'http://api.douban.com/book/subjects?q='+oQ.value+'&alt=xd&callback=fn1';
  33. document.body.appendChild(oScript);
  34. }
  35. //http://api.douban.com/book/subjects?q='+oQ.value+'&alt=xd&callback=fn1&start-index=(当前页*每页显示的条数)&max-results=10(每页显示的条数)
  36. }
  37. }
  38. </script>
  39. </head>
  40. <body>
  41. http://www.douban.com/service/apidoc/reference/
  42. <input type="text" id="q" /><input type="button" id="btn" value="搜索" />
  43. <p id="msg"></p>
  44. <hr />
  45. <div id="list"></div>
  46. </body>
  47. </html>


天天头条数据接口:
   
   
  1. https://toutiao.eastday.com/toutiao_h5/RefreshJP?type=toutiao&picnewsnum=1&jsonpcallback=fn1

接口分享:
   
   
  1. http://www.bejson.com/knownjson/webInterface/

案例三:聚合数据的使用方法。自己动手

   
   
  1. http://www.cnblogs.com/annie00/p/6112487.html


其他jsonp的说明和教程(jq里面的$.ajax()也可以实现跨域):

   
   
  1. http://www.360doc.com/content/14/1030/09/5054188_421070813.shtml
    
    
  1. http://www.cnblogs.com/ccode/p/4871853.html
     
     
  1. http://www.jb51.net/article/46463.htm
jsonp的封装方法:
   
   
  1. http://blog.csdn.net/u013830811/article/details/52718664
    
    
  1. http://blog.csdn.net/liusaint1992/article/details/50959571





指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javacript施加的安全限制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值