js闭包,跨域
js闭包,跨域
闭包
想象一下,你家有个大仓库(函数),仓库里放着各种东西(变量)。一般情况下,你从仓库外面是看不到也拿不到仓库里的东西的。但是,闭包就像是你在仓库里留了一个小窗口,通过这个小窗口,外面的人(其他函数)也能和仓库里的东西打交道。
在 JavaScript 里,闭包就是一个函数可以访问并操作它外部函数作用域里的变量,即使外部函数已经执行完了。也就是说,闭包让变量的值始终保持在内存中,不会随着外部函数的执行结束而被销毁。
闭包有啥用
- 读取函数内部的变量:比如你有一个函数,里面有一些变量,你想在函数外面使用这些变量的值,就可以用闭包来实现。
- 让这些变量的值始终保持在内存中:举个例子,你有一个计数器函数,每次调用它计数器就加 1。如果没有闭包,每次调用函数,计数器都会重新初始化为 0。但用了闭包,计数器的值就能一直保存着,每次调用都会接着上一次的值继续加。
代码示例
function outerFunction() {
let count = 0;
function innerFunction() {
count++;
console.log(count);
}
return innerFunction;
}
// 创建闭包
let counter = outerFunction();
// 调用闭包
counter(); // 输出 1
counter(); // 输出 2
在这个例子中,innerFunction
就是一个闭包,它可以访问 outerFunction
里的 count
变量。即使 outerFunction
执行完了,count
的值也不会被销毁,每次调用 counter
函数(也就是 innerFunction
),count
的值都会增加。
跨域
啥是跨域
你可以把互联网想象成一个超级大的城市,每个网站就像是城市里的不同小区。每个小区都有自己的规则,一般情况下,小区和小区之间是不能随便串门的。在浏览器里,每个网站都有自己的协议(比如 http
或者 https
)、域名(比如 www.example.com
)和端口号(比如 80
或者 443
),这三个东西合起来就像是小区的地址。当你从一个网站(小区)去访问另一个网站(小区),如果这两个网站的协议、域名或者端口号不一样,就会被浏览器认为是跨域访问,默认是不允许的。这是为了保证用户信息的安全,防止一些恶意网站窃取你的数据。
为啥会有跨域问题
浏览器有一个同源策略,就是为了保护用户信息的安全。如果没有这个策略,一些恶意网站就可以随便访问其他网站的数据,比如你的银行账户信息、登录密码等,这会带来很大的安全风险。所以浏览器会限制不同源的网站之间的资源共享和交互。
怎么解决跨域问题
- JSONP(JSON with Padding):这就像是两个小区之间通过一个特殊的信使来传递消息。它的原理是利用
<script>
标签的src
属性不受同源策略限制的特点,通过动态创建<script>
标签来实现跨域数据请求。不过它只支持GET
请求。 - CORS(Cross - Origin Resource Sharing,跨域资源共享):这就像是小区之间签了一个友好协议,允许互相串门。服务器端设置响应头,告诉浏览器这个跨域请求是被允许的。现在大部分浏览器和服务器都支持 CORS,它是解决跨域问题的主流方法。
- 代理服务器:这就像是你在两个小区之间建了一个中转站。你先把请求发给自己小区里的中转站(代理服务器),中转站再把请求转发到另一个小区,然后把另一个小区的响应再返回给你。这样在浏览器看来,请求和响应都是在同一个小区(同源)里进行的,就不会有跨域问题了。
代码示例(CORS)
服务器端(Node.js + Express)
const express = require('express');
const app = express();
// 设置 CORS 响应头
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有域名跨域访问
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
next();
});
// 处理请求
app.get('/data', (req, res) => {
res.json({ message: '这是跨域请求的数据' });
});
const port = 3000;
app.listen(port, () => {
console.log(`服务器运行在端口 ${port}`);
});
客户端(HTML + JavaScript)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
fetch('http://localhost:3000/data')
.then(response => response.json())
.then(data => console.log(data));
</script>
</body>
</html>
在这个例子中,服务器端设置了 CORS 响应头,允许所有域名进行跨域访问,客户端通过 fetch
方法发送跨域请求并获取数据。