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('网络请求失败')
}
}
}
}