js-22同源策略
01同源策略
含义:同源策略是浏览器的一个安全功能,不同源的网页脚本在没有明确授权的情况下,不能读写对方资源。所谓同源是指"协议+域名+端口"三者相同 ``` 1. 浏览器的一个安全功能 如果不使用浏览器此安全策略对你没影响 2. 同源 "协议+域名+端口" http://www.baidu.com:80/index.html => http://www.baidu.com:80/productlist => http://www.baidu.com:8080/productlist => http://www.sina.com:80/productlist => https://www.sina.com:80/productlist 3. 不同源的网页脚本在没有明确授权的情况下,不能读写对方资源。 ``` 1. 浏览器的一个安全功能 如果不使用浏览器此安全策略对你没影响 2. 同源 "协议+域名+端口" http://www.baidu.com:80/index.html => http://www.baidu.com:80/productlist => http://www.baidu.com:8080/productlist => http://www.sina.com:80/productlist => https://www.sina.com:80/productlist 3. 不同源的网页脚本在没有明确授权的情况下,不能读写对方资源。
02跨域
含义: 使用AJAX技术(XMLHttpRequest 对象),从一个网页去请求另一个网页资源时,违反浏览器同源策略限制, 引起的安全问题,称为跨域 备注:localhost和127.0.0.1虽然都指向本机,但也属于跨域 1.跨域错误 前后端分离项目:by CORS policy: No 'Access-Control-Allow-Origin' 2.解决跨域的方案: - 跨域资源共享 cors + 服务端设置,允许其它源访问服务端资源 + nodejs实现:CORS 跨域资源共享 response.setHeader('Access-Control-Allow-Origin', '*') - 不使用ajax技术 -> 使用jsonp技术 - 代理服务器
03jsonp技术【面试题考试题】
jsonp技术基本原理 1.利用HTML的<script>标签天生可以跨域这一特点,用其加载另一个域的json数据. 2.加载完成后会自动运行一个回调函数通知调用者。此过程需要另一个域的服务端支持 jsonp技术实现 【大厂面试】 jsonp条件: 1. 服务端支持 响应数据包裹在一个函数中返回 { resultCode:1, resultInfo:{ username:'admin', age:18 } } 这种形式: callBack({ resultCode:1, resultInfo:{ username:'admin', age:18 } }) 2. 前端 后端反馈callback函数,调用显示数据 此函数自己执行 function callBack(data){ } 缺点: 只支持get请求
【掌握】json技术实现
<button class="btn">确定</button> <script> const btn = document.querySelector('.btn') btn.addEventListener('click', function () { getProductList('http://10.7.178.115:8088/api/jsonp/list') }) /* 发生jsonp请求 实现原理: 动态构造script标签,将请求url接口地址作为script属性src值 */ function getProductList(url) { //动态创建script标签 let scriptEle = document.createElement('script') //<script> scriptEle.setAttribute('src', url) document.body.appendChild(scriptEle) } /* jsonp响应数据: callBack 由后端提供 */ function callback(result) { console.log(result); } </script>
练习: 使用jsonp技术请求用户列表接口数据 接口地址: http://10.7.178.115:8088/api/jsonp/list 响应数据函数名为: callback 扩展: 使用面向对象class封装实现 class1: class onResponse{ //发送请求 send(url){ //动态创建script标签 let scriptEle = document.createElement('script') //<script> scriptEle.setAttribute('src', url) document.body.appendChild(scriptEle) //callback只能在这里调用 window.callback = function(data){ console.log(data) //callback是window对象 } } } class2:回调函数的实现 class onResponse{ //发送请求 send(url){ //动态创建script标签 let scriptEle = document.createElement('script') //<script> scriptEle.setAttribute('src', url) document.body.appendChild(scriptEle) } //处理异步请求结果数据 responseDate(callResault){ window.callback = function(data){ callResault(data) } } } var jsonpObj = new onResponse() jsonpObj.send(' http://10.7.178.115:8088/api/jsonp/list') jsonpObj.responseDate(function(data){ console.log(data) })
04回调函数
回调函数: 一个函数作为另一个函数的参数,在另一个函数中调用,这样的函数称为回调函数 解决问题: 处理异步请求结果
05同步和异步
同步与异步 同步: 一件事情做完才能开始下一件事 异步: 多个事情同时并发执行 异步操作: 当一个操作开始执行后,主程序无需等待它的完成,可以继续向下执行。 此时该操作可以跟主程序同时(并发)执行。 异步任务: ajax异步网络通讯技术 setTimeout 异步任务 问题: 异步任务完成后返回结果处理问题? 解决办法: 回调函数 (回调函数可以解决异步任务问题 ex: console.log('准备茶叶 2分钟'); setTimeout(function(){ console.log('准备烧水 10分钟'); },0) console.log('泡茶 1分钟');
06ajax封装
1.为什么要封装AJAX? 每次ajax请求都要重复: - 创建XMLHttpRequeset对象, - 与服务器建立连接, - 发送请求, - 处理响应数据。 可以将每次请求的不同点, 如url地址、请求方法和处理响应方式提取出来,封装成工具函数
ajax({ method:'post', url:'http://127.0.0.1:8088/api/login', //参数 data:{ username:'admin', password:123 }, success:function(data){ //成功处理 console.log('成功',data); }, error:function(error){ //失败处理 console.log('失败',error) } }) //处理数据对象 - 转变 - 键值对的形式 function formateParam(data){ let arr = [] //遍历对象的属性 for(let key in data){ //data:{username:'admin',password:123} arr.push(`${key}=${data[key]}`) } return arr.join('&') //'username='admin'&password=123 } function ajax(options){ //1.ajax对象 let xhr = new window.XMLHttpRequest() //2.链接服务器 let params = formateParam(options.data) //3.建立链接 let method = options.method.toUpperCase() //请求方法统一大写 if(method == 'GET'){ xhr.open(method,options.url + '?' + params) xhr.send() }else if(method == 'POST'){ xhr.open(method,options.url) //设置表 xhr.setRequestHeader('content-type','application/x-www-form-urlencoded') xhr.send(params) } //4.处理响应数据 xhr.onreadystatechange = function(){ //就绪 if(xhr.readyState == 4){ //状态 if(xhr.status == 200){ let data = xhr.responseText options.success(data) }else{ options.error('网络请求失败') } } } }
if(xhr.status == 200){ let data = xhr.responseText options.success(data) }else{ options.error('网络请求失败') } } } }