普通视图

发现新文章,点击刷新页面。
昨天 — 2025年5月19日首页

🔒“同源策略”到底限制了啥?搞懂它,跨域就不再是问题!

作者 tianchang
2025年5月19日 16:06

✅ 什么是同源策略(Same-Origin Policy)?

同源策略是浏览器最核心的安全机制之一,它限制不同源之间的交互行为,防止恶意网站窃取用户数据。

🔑 “同源”的定义:

要满足以下三个条件,两个资源才算是“同源”

条件 示例
协议相同 http vs https ❌ 不同源
域名相同 a.example.com vs b.example.com ❌ 不同源
端口相同 example.com:80 vs example.com:8080 ❌ 不同源

例如

http://example.com:80
vs
https://example.com:443 → ❌ 不同源

🚧 同源策略会限制哪些操作?

操作类型 是否受限 说明
读取 Cookie / LocalStorage ✅ 受限 无法访问其他源的数据
发送 AJAX 请求 ✅ 受限 请求可以发出,但响应无法读取(除非 CORS)
DOM 操作 ✅ 受限 不同源的页面不能互相操作 DOM
<img src> 请求 ❌ 不受限 可以加载不同源的图片
<script src> 请求 ❌ 不受限 可用于加载第三方脚本(但存在 XSS 风险)
<link href> 请求 ❌ 不受限 样式文件可跨域加载

🤯 为什么需要同源策略?

  • 防止 CSRF(跨站请求伪造):你登录着某个网站,另一个恶意站点偷偷发请求窃取你的权限。

  • 防止 隐私泄露:通过 iframe、cookie 等手段窃取用户敏感信息。

  • 限制第三方脚本的非授权访问


🎯 常见解决方案(跨域)

  1. CORS(推荐)
    后端设置响应头 Access-Control-Allow-Origin 等,允许指定源访问。

  2. JSONP(仅支持 GET,已过时)
    利用 <script> 不受同源限制的特性。

  3. 反向代理(如 Nginx)
    本质:让前端请求看起来是“同源”的路径,比如 /api → 代理到后端服务器

  4. PostMessage
    用于 iframe、window 跨源安全通信。


🧨 为什么“不是所有跨域都能 CORS”?

有些跨域问题根本不是 CORS 能解决的,下面来看一个案例。

🔍 示例 某些第三方接口不支持 CORS

比如你想访问一个第三方开放接口 https://thirdparty.com/data,但这个接口压根不支持跨域响应头。

即使你发送请求:

fetch('https://thirdparty.com/data')

也会报错:

Access to fetch at 'https://thirdparty.com/data' from origin 'https://yourdomain.com' has been blocked by CORS policy

因为第三方服务没有设置 CORS,你根本无法通过浏览器读取返回的数据

👉 解决方法:

  • 后端中转(如你自己的服务转发请求)

  • 或使用服务器代理请求,再将数据返回给前端。


🧠 总结

同源策略是浏览器的“护城河”,保护用户免受恶意站点的攻击。想要合理“越过”它,就要了解它!

记住这句话:

“不是所有跨域都能 CORS,代理才是真正的解法。”

昨天以前首页

js中是否存在真正的异步?

作者 tianchang
2025年5月16日 23:29

JavaScript 本身没有“异步执行”的能力,所谓异步,其实都是“通过回调 + 事件循环机制实现的异步行为”。


🔹 1. JS 是单线程的语言

JavaScript 的运行环境(如浏览器、Node.js)中,JS 本身只在主线程中执行,不能同时干两件事。比如:

console.log(1) 
setTimeout(() => console.log(2), 1000) 
console.log(3)`

虽然 setTimeout 看起来是“异步的”,但本质上:

  • setTimeout 把回调函数登记给浏览器或 Node 的 “定时器模块”

  • JS 主线程继续执行;

  • 等 1 秒后,事件循环机制(Event Loop) 将回调函数“推”到 JS 主线程队列中执行。

所以 JS 本身没有“异步线程”,异步操作是环境提供的能力(浏览器/Node 的 Web APIs)。


🔹 2. 所有异步行为,归根结底都是「延迟执行的回调函数」

举例:PromisesetTimeoutfetchasync/await,都可以还原为回调逻辑。

setTimeout(() => console.log('A'), 1000)

==就是注册一个回调函数==,延迟执行。


🔹 3. Promise 也只是对“回调”的封装

new Promise((resolve) => {   setTimeout(() => {     resolve('done')   }, 1000) }).then(result => {   console.log(result) })

核心仍然是:注册回调,只不过 .then 把回调收敛到一个更好管理的语法结构中。

❌
❌