------------------------------------------------------跨域问题 以及jsonp方法举例--------------------------------------------------------
ajax的跨域的问题:
<!-- 不允许跨域
跨域:不同域(不同源)
跨域是浏览器层面拒绝跨域 数据能获取 但不显示
只要不符合同源,就是跨域,资源没有明确表示允许,那么就是不允许,ajax失败 -->
同源策略 <!-- 同源策略,是浏览器共同约定的,基于安全的角度的请求规则 -->
浏览器页面和请求的地址 同域(同源):同服务,同域名,同端口
发起请求和目标请求 - 同协议:http,https,ftp,file
- 同域名:www.baidu.com,baike.baidu.com ( 域名 ?拼接数据 )
- 同端口:xxxx:8080,xxxx:80
怎么解决:
jsonp : ajax无法请求未经允许的跨域资源
ajax的核心是XHR对象
jsonp不是ajax,没有xhr对象
后台cors :让资源主动设置,允许请求,
服务器代理:(自己搭服务器 请求后拿数据 再渲染网页 获取时没有浏览器就不存在跨域问题)
<!--
跨域的报错信息
- No 'Access-Control-Allow-Origin' header is present on the requested resource.
- 请求的资源上不存在'Access-Control-Allow-Origin'标头。
- 访问控制允许源 -->
jsonp原理
用script标签特性 连接后台 回调函数取数据
⭐先定义函数再引入后台文件
<!-- jsonp利用的是某些html可以引入外部资源的特点 比如a的href img的src
只有script标签会将引入的文本文件作为js代码解析
引入的php文件:php文件先被服务器运行(需要运行服务器才能解析php) php返回的字符,被script标签作为js代码解析
返回的字符是js代码 就直接运行 ⭐echo "fn(数据)"
返回的是一个函数也会运行 此时函数如果带着参数==>数据从后台移动到前端
script标签引入后台文件 返回的字符是一个函数调用 携带数据作为实参 前端在页面定义这个函数 且设置形参接收数据 完成跨域 -->
jsonp的发送数据
script标签引入后台文件的路径上拼接数据
只能get发送 不用ajax 没有send()不能post发送 且有缓存bug 需要拼接时间戳完整封装jsonp
<script>
jsonp('http://127.0.0.1/ws2011/jsonp/data/data4.php',function(res){
alert(res)
},{
a:10,
b:20,
cb:"asdasd", 函数的名字不固定 函数名发送给后端 后端接手后echo调用函数带数据出来
//后端接收函数名时 需要一个字段名 确定哪一部分数据是函数名 字段名现在是cb 字段名不固定
//https://blog.csdn.net/hpasdabc?spm=1000.2115.3001.5343
columnName:"cb"
//函数体声明时 函数名依靠字段名cb来查找 字段名改变 就要修改函数↓
//把字段名保存到变量 columnName 函数体声明时 函数名根据
⭐解析columnName保存的字段名 再解析字段名找到对应的函数名
})
function jsonp(url,success,data={}){
1.解析要发送的数据
let str = "";
for(let i in data){
str += `${i}=${data[i]}&`
}
2. 创建script标签
let script = document.createElement("script")
script.src = url + "?" + str + "_qft_=" + Date.now();
document.body.appendChild(script)
3. 借助window使用赋值式,定义全局函数 不全局php调用不到 作用域问题
//注意中括号解析后的数据是什么 ⭐解析columnName保存的字段名 再解析字段名找到对应的函数名
window[data[data.columnName]] = function(res){
success(res)
}
}
</script>
jsonp 官方没有失败的提示 自己设置计时 超时返回警告