1. 跨域
1.1 同源策略
编程中的同源,比较的是两个url是否同源。
主要看下面三个方面:
- 协议是否相同(http https file)
- 主机地址是否相同(www.xxx.com 127.0.0.1)
- 端口(0~65535)(http默认端口是80;https默认端口是443;MySQL默认端口3306)
协议、主机地址、端口组成一个“源”。
如果两个url的协议、主机地址、端口都相同,那么这两个url是同源的,否则就是非同源。
如果非同源,那么以下三种行为会受到限制:
- Cookie 无法操作
- DOM 无法操作
- Ajax请求无效(请求可以发送,服务器也会处理这次请求,但是响应结果会被浏览器拦截)
违反了同源策略的请求,叫做跨域请求。
1.2 解决跨域
主流的方案有两种:分别是JSONP和CORS.
1.2.1 CORS
由于XHR对象被W3C标准化之后,提出了很多XHR Level2的新构想,其中新增了很多新方法(onload、response…)和CORS跨域资源共享。浏览器升级后开始支持CORS方案,从IE10开始支持。
CORS方案,就是通过服务器设置响应头来实现跨域。
CORS才是解决跨域的真正解决方案。
- 前端需要做什么?
- 无需做任何事情,正常发送Ajax请求即可。
- 后端需要做什么?
- 需要加响应头 。或者使用第三方模块 cors 。
1.2.2 JSONP
是程序员被迫想出来的解决跨域的方案。
JSONP方案和Ajax没有任何关系
JSONP方案只支持GET请求
JSONP没有浏览器兼容问题,任何浏览器都支持。
-
原理
- 客户端利用 script 标签的 src 属性,去请求一个接口,因为src属性不受跨域影响。
- 服务端响应一个字符串
- 客户端接收到字符串,然后把它当做JS代码运行。
后端接口代码:
app.get('/api/jsonp', (req, res) => { // res.send('hello'); // res.send('console.log(1234)'); // res.send('abc()') // res.send('abc(12345)') // 接收客户端的函数名 let fn = req.query.callback; let obj = { status: 0, message: '登录成功' }; let str = JSON.stringify(obj); res.send(fn + `(${str})`); });
前端代码:
<script> // 提前准备好一个函数 function xxx(res) { console.log(res) } </script> <script src="http://localhost:3006/api/jsonp?callback=xxx"></script>
-
前端需要做什么?
- 如果使用jQuery,$.ajax({ dataType: ‘jsonp’ }),必须指定dataType选项为jsonp即可
-
后端需要做什么?
- 如果使用express,那么直接调用
res.jsonp(数据)
即可。
- 如果使用express,那么直接调用
1.3 小结
方案 | 前端 | 后端 |
---|---|---|
CORS | × | 设置响应头 |
JSONP(原生) | 1. 准备一个函数;2. 使用script的src发送请求 | 响应函数调用 |
JSONP(jQuery) | 1. 还是调用$.ajax();2. 必须指定dataType: ‘jsonp’ | res.jsonp(数据) |
2.递归
编程语言中,函数直接或间接调用函数本身,则该函数称为递归函数。
简单来说,递归就是函数自己调用自己。因为是自己调用自己,所以容易出现死循环,所以使用递归的时候一般会
注意两个控制条件:
1. 设置调用条件,满足条件,则函数自己调用自己。
2. 当然,有些时候需求比较特殊,也可以不设置跳出条件,永久性处理需求。
3. 设置跳出条件,满足条件,则跳出函数的调用。
// 案例:
// 1.求和1~100的和。
// 2.求等差数列的和。(公式: 首项+(N-1)*公差 )
// 3.求数组中所有项的和。(公式: 开始值和结束值一样大就结束了 )
// 1
function getSum(n) {
if (n ==1 ) {
return 1;
}
return n + getSum(n-1);
}
// alert(getSum(100))
// 2
function foo2(n, a, b) {
if (b==1){
return n;
}
return n+(b-1)*a + foo2(n,a,b-1);
}
// alert(foo2(1, 2, 3));
// 3
function foo3(arr, s, e) {
if (s == e) {
return arr[s];
}
return arr[s] + foo3(arr, s+1, e);
}
// alert(foo3([1,2,3,4,5], 0, 4));