# 同源访问策略
* 同源策略是 Netscape 提出的一个著名的安全策略;
* 同源策略是浏览器最核心最基础的安全策略;
* 现在所有的可支持 Javascript 的浏览器都会使用这个策略;
* Web 构建在同源策略基础之上,浏览器对非同源脚本的限制措施是对同源策略的具体实现。
# 同源策略的含义详解
* DOM 层面的同源策略:限制了来自不同源的 document 对象或 JS 脚本,对当前 document 对象的读取或设置某些属性。
* Cookie 和 XMLHttpRequest 层面的同源策略:只有和本网页同源的脚本才会被执行,有时,AJAX 已经加载不同源的脚本,但绝对不会被执行。
* 同源策略的非绝对性:
* 同源策略通常允许进行跨域写操作、通常允许跨域资源嵌入、通常不允许跨域读操作;
* script、img、iframe、link、video、audio 等带有 src 属性的标签可以从不同的域加载和执行资源,同源策略关注的是加载 JS 的页面所在的域,而不是页面内存放的 JS 文件的域。
* 其他插件的同源策略:Flash 等浏览器加载的第三方插件也有各自的同源策略,只是这些同源策略不属于浏览器原生的同源策略,若有漏洞则可能被黑客利用,从而留下 XSS 攻击的后患。
# 使用 CROS 实现跨域访问
增加一个响应头就可以实现跨域效果了。
~~~
res.append('Access-Control-Allow-Origin', '*');
~~~
# 使用 JSONP 实现跨域访问
虽然我们不能直接使用 AJAX 跨域发送请求,但是我们可以利用一些标签是可以跨域。
* 在页面中需要先声明函数,该函数的名称需要和服务器端返回的数据对应,该函数接受一个参数;
* 大多数情况,会把函数名提交到服务器端。
Express 中的响应对象中有一个方法 jsonp,提供这样的功能。
~~~
res.jsonp(null);
// => callback(null)
res.jsonp({user: 'tobi'});
// => callback({"user": "tobi"})
res.status(500).jsonp({error: 'message'});
// => callback({"error": "message"})
~~~
默认情况下,JSONP 回调名称是 callback,可以请求参数进行修改。
~~~
// 调用的时候传递参数 ?callback=foo
res.jsonp({user: 'tobi'});
// => foo({"user": "tobi"})
app.set('jsonp callback name', 'cb');
// ?cb=foo
res.status(500).jsonp({error: 'message'});
// => foo({"error": "message"})
~~~
## JSONP 案列
需求:当输入框的内容发生变化发送请求(调用百度的 JSONP 接口)来获取结果显示出来
* 通过 script 标签来设置 src 为请求路径;
* 先提供函数声明。
```
<input type="text" id="keyword">
<script>
function fn(obj) {
console.log(obj);
var data = obj['s'];
var ulEle = document.getElementsByTagName('ul')[0] || document.createElement('ul');
ulEle.innerHTML = ''; // 清空原来的搜索内容
data.forEach(function (ele) {
var liEle = document.createElement("li");
liEle.innerText = ele;
ulEle.appendChild(liEle);
});
document.body.appendChild(ulEle);
}
</script>
<script>
var inputEle = document.getElementById('keyword');
inputEle.onkeyup = function () {
// 删除原来的 script 标签
var oldScriptEle = document.getElementById('baiduJsonp');
if(oldScriptEle){
document.body.removeChild(oldScriptEle);
}
//创建 script 标签插入到页面中
var newScriptEle = document.createElement('script');
newScriptEle.setAttribute('id', 'baiduJsonp');
newScriptEle.setAttribute('src','https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=' + inputEle.value + '&cb=fn');
document.body.appendChild(newScriptEle);
}
</script>
```
- NodeJs
- 01-万维网
- 02-CS 架构 VS BS 架构
- 03-Web 服务器访问流程
- 04-url
- 05-网络传输协议
- 06-HTTP 协议
- 07-报文
- 08-命令行界面
- 09-什么是 Node.js
- 10-环境安装及配置
- 11-JavaScript 代码运行环境
- 12-全局对象
- 13-Buffer
- 14-模块化
- 15-EventEmitter
- 16-path模块
- 17-流式操作
- 18-包
- 19-模板技术
- 20-ejs入门
- 21-express
- 01-什么是express
- 02-Hellow Express
- 03-静态资源服务
- 04-路由
- 05-模块化路由处理程序
- 06-中间件
- 07-手动实现中间件
- 08-常用内置中间件和第三方中间件
- 09-响应
- 10-获取请求参数
- 11-Express 中使用模板引擎
- 22-web存储与安全
- 01-cookie
- 02-sessionStorage
- 03-localStorage
- 04-base64
- 05-https
- 06-同源策略