及其封装(下)

学习目标

节数 知识点 要求
第一节(原生Ajax封装) 为什么函数封装 了解
封装思路 掌握
封装ajax实现步骤 掌握
第二节(什么是跨域) 同源策略和非同源策略 掌握
跨域产生的原因 掌握
第三节(跨域解决方案) cors资源共享 掌握
后台代理 掌握
jsonp原理以及实现 理解
第四节(跨域实例练习) 跨域获取百度搜索接口数据 掌握
模拟百度搜索 掌握

第一节 原生Ajax封装

1.1 封装函数

把共同的 同样的功能封装成一个函数 ,使用的时候 直接调用函数名就好了

() 就是一个函数 带有参数的函数,调用()获取到当前的数据,return

<div id='div1'></div>
<div id='div2'></div>
<div id='div3'></div>
<div id='div4'></div>

<div id='div5'></div>

<script>

​ //JS获取div

​ var div1= document.getElementById('div1');

​ var div2= document.getElementById('div2');

​ var div3= document.getElementById('div3');

var div4= document.getElementById('div4');

function $(id){

​ return document.querySelector(id);

}

$('#div1');

1.2 Ajax封装

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.2.1 封装思路

1.封装函数 myAjax() 请求参数:请求方式 请求地址 请求数据 回调函数

2.myAjax({type:'',url:'',data:{},success:fun})

3.定义函数 function myAjax(jsonData)

4.函数 封装ajax 原生ajax:数据拼接 data='uname=qq&upsd=123'

get方式: open('get',url?data) send(null)

post方式:open('post',url) send(data)

1.2.2 原生的ajax请求

document.getElementById('btn').onclick=function(){

​ var name=document.getElementById('name').value;

​ var psd=document.getElementById('psd').value;

​ if(window.XMLHttpRequest){

​ xhr = new XMLHttpRequest();//i7 主流浏览器都支持

​ }else if(window.ActiveXObject){

​ xhr = new ActiveXObject();//ie5 ie6

​ }

​ xhr.open('get','06get_json.php?uname='+name,true);

​ xhr.send();

​ xhr.onreadystatechange=function(){

​ if(xhr.readyState==4 && xhr.status==200){

​ console.log(xhr.responseText);//返回xhr 字符串格式

​ console.log(JSON.parse(xhr.responseText));

​ }

​ }

​ }

1.2.3封装代码

document.getElementById('btn').onclick=function(){

var name=document.getElementById('name').value;

var psd=document.getElementById('psd').value;

​ myAjax({

​ type:’ get',

​ url:'05ajax.php',

​ data:{

​ uname:name,

​ upsd:psd

​ },

​ success:function(aa){

​ console.log(aa);

​ }

​ })

​ }

function myAjax(jsonData){

​ var xhr=new XMLHttpRequest();

​ var newData='';

if(jsonData.data){

​ var str='';

​ var arr=[];

​ for(var key in jsonData.data){

​ str=key+'='+jsonData.data[key];

​ arr.push(str);

​ }

​ newData=arr.join('&');//最终处理的数据拼接结果

}

if(jsonData.type.toLowerCase()=='get'){

​ xhr.open('get',jsonData.url+'?'+newData,true);

​ xhr.send();

} else if(jsonData.type.toLowerCase()=='post'){

​ xhr.open('post',jsonData.url,true);

​ xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded;charset=utf-8');

​ xhr.send(newData);

}

xhr.onreadystatechange=function(){

​ if(xhr.readyState==4){

​ if(xhr.status==200){

​ jsonData.success(xhr.responseText);

​ }

​ }

}

}

本章作业

1.封装ajax

2.使用封装好的ajax请求一个本地的json文件,并渲染页面

第二节 什么是跨域

2.1 跨域问题产生的原因

浏览器安全问题:浏览器的同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。从一个域上加载的脚本不允许访问另外一个域的文档属性

当前的地址下去访问浏览器上另外一个地址,不允许我们访问,浏览器阻止我们访问,安全

跨域,指的是从一个域名去请求另外一个域名的资源。即跨域名请求!跨域时,浏览器不能执行其他域名网站的脚本,是由浏览器的同源策略造成的,是浏览器施加的安全限制。

跨域的严格一点来说就是只要协议,域名,端口有任何一个的不同,就被当作是跨域

访问游侠客旅游 分页网址:http://www.youxiake.com/search/line?keyword=&select=1&class_tab=0&area=0&day=1

【代码演示】

<script src='js/myAjax.js'></script>
<script>

​ myAjax({

​ type:'get',

​ url:' http://www.youxiake.com/search/line?keyword=&select=1&class_tab=0&area=0&day=1

',

​ success:function(res){

​ console.log(JSON.parse(res));

​ }

​ })

</script>

2.2 同源策略

同源策略是由 Netscape 公司提出的一个著名的安全策略,所有支持 JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当页面在执行一个脚本时会检查访问的资源是否同源,如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

2.3 为什么要跨域?

现实工作开发中经常会有跨域的情况,因为公司会有很多项目,也会有很多子域名,各个项目或者网站之间需要相互调用对方的资源,避免不了跨域请求。

本章作业

1.什么是同源策略

2.什么是跨域

第三节 跨域解决方案

1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

3.1 后台代理

浏览器阻止跨域请求,利于后台去访问服务器资源,然后本地访问php后台返回的数据。

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>

​ $.ajax({

​ type:'get',

​ url:'08houtai.php',

​ dataType:'json',

​ success:function(res){

​ console.log(res);

​ }

​ })

​ </script>

php文件:

$res=file_get_contents('http://www.youxiake.com/xxx ');

echo $res;

3.2 iframe跨域

1.)父窗口:(http://www.domain.com/a.html)
 
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
    document.domain = 'domain.com';
    var user = 'admin';
</script>
2.)子窗口:(http://child.domain.com/b.html)
 
<script>
    document.domain = 'domain.com';
    // 获取父窗口中变量
    alert('get js data from parent ---> ' + window.parent.user);
</script>

3.3 跨域资源共享(CORS)

普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置

CORS是一个W3C标准,全称是“跨域资源共享”(Cross-origin resource sharing)。

它允许浏览器向跨源服务器发出XMLHttpRequest请求,从而克服了AJAX只能同源发送请求的限制。

实现CORS主要在于服务器的设置,关键在于服务器HTTP响应报文首部的设置。前端部分大致还是跟原来发AJAX请求没什么区别,只是需要对AJAX进行一些相关的设置。

CORS的两种请求

浏览器将CORS分为两种请求,一种是简单请求,另外一种对应的肯定就是非简单请求

阮一峰:http://www.ruanyifeng.com/blog/2016/04/cors.html

3.4 porxy代理

原理:让代理服务器请求目标地址,因为请求是在服务端进行的,在服务端不存在跨域,从而解决跨域问题

实现:将原地址绑定在代理服务器下,让代理服务器发送请求。

3.5 jsonp跨域

3.5.1 jsonp跨域的原理

动态创建script标签,利用script标签的src属性可以获取任何域下的js脚本,通过这个特性(也可以说漏洞),服务器端不在返回json格式,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域

【代码演示】
<script>

​ function demo(res){//res形参 res后台返回给我的数据

​ console.log(res);

​ }

</script>

<script src='09jsonp.php?callback=demo'></script>

php:

<?php

//接收函数变量名

fun=_GET['callback'];

//比如 虚拟数据 创建数组

$arr=array('msg'=>'ok','info'=>'虚拟后台数据');

obj=json_encode(arr);//数组--字符串对象

// $obj='hello';

echo "fun(obj)";

?>

【代码演示】
<script>

​ function demo(res){

​ console.log(res);

​ }

</script>

 <script src='http://suggestion.baidu.com/su?cb=demo&wd=ajax'></script>

3.5.2 不受同源限制的情况

当然也有不受同源限制的情况存在,主要有以下列举的:

\1. script标签允许跨域嵌入脚本,稍后介绍的JSONP就是利用这个“漏洞”来实现。

\2. img标签、link标签、@font-face不受跨域影响。

\3. videoaudio嵌入的资源。

\4. iframe载入的任何资源。(不是iframe之间的通信)

\5. 和``的插件。

\6. WebSocket不受同源策略的限制。

本章作业

1.跨域的解决方式有哪几个

2.jsonp解决跨域的原理

第四节 jsonp跨域

4.1 百度jquery跨域请求

【语法】

        $.ajax({
            type: "get",
            async: false,
            url: "http://localhost:8080/getdata.php",
            dataType: "jsonp",
            jsonp: "callback",//传递给请求处理程序或页面的,标识jsonp回调函数名(一般为:callback)
            jsonpCallback: "GetData",//callback的function名称
            success: function (data) {
                console.log(data);
            },
            error: function () {
                alert('fail');
            }
});

语法解析参数:

jsonp
在一个jsonp请求中重写回调函数的名字。这个值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,
比如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。

jsonpCallback
为jsonp请求指定一个回调函数名。这个值将用来取代jQuery自动生成的随机函数名。
这主要用来让jQuery生成一个独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理

【百度代码演示】

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>

​ var val='爱';//input里面获取的

​ $.ajax({

​ type:'get',

​ url:'http://suggestion.baidu.com/su?wd=ajax',

​ dataType:'jsonp',//数据类型jsonp格式

​ jsonp:'cb',//定义回调函数参数名字 后台接收的函数名 默认callback 如果后台用的默认的 可以省略的

​ jsonpCallback:"demo",//可以省略: 默认:jquery随机数字()

​ success:function(res){

​ console.log(res);

​ }

​ })

​ </script>

4.2 jsonp优缺点

4.2.1优点

1.它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制,JSONP可以跨越同源策略
2.它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;   
3.在请求完毕后可以通过调用callback的方式回传结果。
将回调方法的权限给了调用方。这个就相当于将controller层和view层终于分开了。
我提供的jsonp服务只提供纯服务的数据,至于提供服务以 后的页面渲染和后续view操作都由调用者来自己定义就好了。
如果有两个页面需要渲染同一份数据,你们只需要有不同的渲染逻辑就可以了,
逻辑都可以使用同 一个jsonp服务。

4.2.2 缺点

1它只支持GET请求而不支持POST等其它类型的HTTP请求
2它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
 
3 jsonp在调用失败的时候不会返回各种HTTP状态码。
4缺点是安全性。万一假如提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的。
那么结果是什么?所有调用这个 jsonp的网站都会存在漏洞。
于是无法把危险控制在一个域名下…所以在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 学习目标 节数知识点要求第一节(原生Ajax封装)为什么函数封装了解封装思路掌握封装ajax实现步骤掌握第二节(什...
    yy666777阅读 994评论 0 0
  • 1. 什么是跨域? 跨域一词从字面意思看,就是跨域名嘛,但实际上跨域的范围绝对不止那么狭隘。具体概念如下:只要协议...
    他在发呆阅读 4,196评论 0 0
  • 1. 什么是跨域? 跨域一词从字面意思看,就是跨域名嘛,但实际上跨域的范围绝对不止那么狭隘。具体概念如下:只要协议...
    w_zhuan阅读 3,532评论 0 0
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 12,186评论 16 22
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 13,585评论 0 11