Ajax03
ajax同源限制
解决方法
同源策略
同源拥有相同的协议、域名和端口,那么这两个页面就属于同一个源,其中只要有一个不相同,就是不同源。
非同源情况
http://www.baidu.com:3000 和 http://www.tengxun.com:3000 //域名不同
http://www.baidu.com:3000 和 https://www.baidu.com:3000 //协议不同
http://www.baidu.com:3000 和 https://www.baidu.com:3001 //端口不同
为什么出现同源政策
同源政策是为了保证用户信息的安全,防止恶意的网站窃取数据。不是同源的两个页面A B 未经许可不可以相互访问资源,发送Ajax请求
不受同源策略限制的
一些特别的情况
- 页面中的连接,重定向,表单提交不会受影响
- 跨域的引入
<script>
标签中的src属性可以加载我不的js文件,通过该属性可以想不同源的页面发送请求,src属性也不一定只能访问以js结尾的资源,但需要返回合法的课执行的js代码 。
实际操作(报错信息)
在一些情况我们需要访问非同源网页资源,该怎么解决?
解决方案
一.JSONP
jsonp : json with padding
不许与Ajax请求,只是模仿了Ajax请求
主要利用了script的src属性实现
**JSONP代码封装 **
function jsonp (options) {
// 动态创建script标签
var script = document.createElement('script');
// 拼接字符串的变量
var params = '';
for (var attr in options.data) {
params += '&' + attr + '=' + options.data[attr];
}
// myJsonp0124741
var fnName = 'myJsonp' + Math.random().toString().replace('.', '');
// 它已经不是一个全局函数了
// 我们要想办法将它变成全局函数
window[fnName] = options.success;
// 为script标签添加src属性
script.src = options.url + '?callback=' + fnName + params;
// 将script标签追加到页面中
document.body.appendChild(script);
// 为script标签添加onload事件
script.onload = function () {
document.body.removeChild(script);
}
}
//调用
jsonp({
url:[请求地址],
data:[请求数据],
success:function(data){
//data 为响应的数据
}
})
二.CORS
CORS : Cross-origin resuorce sharing(跨域资源共享)
允许客户款发送Ajax请求,克服同源策略对Ajax请求的影响
主要是服务端设置响应头
相当于在服务器端设置白名单
白名单中的内容
- 设置客户端的访问方式,post,get…
- 允许怎样的客户端访问
怎么知道什么样的客户端可以进行访问?
一般简单的请求,浏览器端发送请求时 在header中添加origin请求字段,服务器响应也会设置COPS头部字段,Access-Control-Allow-Origin
// 拦截所有请求
app.use((req, res, next) => {
// 1.允许哪些客户端访问我
// * 代表允许所有的客户端访问我
// 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
// 2.允许客户端使用哪些请求方法访问我
res.header('Access-Control-Allow-Methods', 'get,post')
// 允许客户端发送跨域请求时携带cookie信息
res.header('Access-Control-Allow-Credentials', true);
next();
});
了解另外两个概念
1.简单请求
2.预检请求
简单请求
使用下列方法之一:
GET
HEAD
POSTContent-Type 的值仅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded
预检请求
使用了下面任一 HTTP 方法:
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCHContent-Type 的值不属于下列之一:
application/x-www-form-urlencoded
multipart/form-data
text/plain
HTTP响应首部字段
Access-Control-Allow-Origin
允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符*,表示允许来自所有域的请求
Access-Control-Expose-Headers
让服务器把允许浏览器访问的头放入白名单
Access-Control-Max-Age
该请求的有效时长
Access-Control-Allow-Credentials
当浏览器的credentials设置为true时是否允许浏览器读取response的内容
Access-Control-Allow-Methods
允许请求的方式
Access-Control-Allow-Headers
实际请求中允许携带的首部字段。
三.服务器端处理
node中通过request请求模块实现
//3000端口服务器
//创建服务器代码省略
//引入request模块
const request = require('request')
app.get('/request1',(err,response,body)=>{
request('http://localhost:3001/request2',(err,res,body)=>{
res.send(body);
})
})
app.get('/cross', (req, res) => {
res.send('ok')
});
小结:Ajax03的笔记
内容:同源政策以及解决方式
再接再厉