浏览器同源策略(Same-Origin Policy, SOP)是一种用于限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互的安全机制。这一策略的核心目标是防止跨站脚本攻击(Cross-Site Scripting, XSS)和其他跨站请求伪造(Cross-Site Request Forgery, CSRF)攻击。
目录
4.2 CORS(Cross-Origin Resource Sharing)
![](/qrcode.jpg)
1 什么是“同源”?
在同源策略中,“源”由以下三部分组成:
- 协议:如
http
、https
。 - 域名:如
example.com
。 - 端口:如
80
(http 默认端口)或443
(https 默认端口)。
如果两个 URL 的协议、域名和端口都相同,则它们被认为是同源的。例如:
http://example.com/page1
和http://example.com/page2
是同源的。http://example.com
和https://example.com
不是同源的(不同的协议)。http://example.com
和http://example.net
不是同源的(不同的域名)。http://example.com:80
和http://example.com:8080
不是同源的(不同的端口)。
2 同源策略的应用
同源策略在浏览器中主要应用于以下几种场景:
- DOM:阻止不同源的文档相互访问彼此的 DOM。
- Cookie:仅允许同源的脚本访问相应源的 Cookie。
- AJAX 请求:阻止一个源的脚本发送跨源的 AJAX 请求。
3 浏览器同源策略的示例
为了更好地理解同源策略,我们通过一个简单的例子来展示其工作原理。
假设有两个不同的网页:
http://example.com/main.html
http://example.org/other.html
在 http://example.com/main.html
中尝试访问 http://example.org/other.html
的 DOM 元素。
我们新增一个main.html:
<!DOCTYPE html>
<html>
<head>
<title>Main Page</title>
</head>
<body>
<h1>This is the main page</h1>
<iframe src="http://example.org/other.html" id="iframe" style="display:none;"></iframe>
<script>
document.getElementById('iframe').onload = function() {
try {
var iframeDoc = document.getElementById('iframe').contentDocument;
var iframeContent = iframeDoc.body.innerHTML;
console.log(iframeContent);
} catch (e) {
console.error('Cross-origin access error: ', e);
}
};
</script>
</body>
</html>
在此示例中,main.html
尝试通过 <iframe>
元素加载 other.html
并访问其 DOM。由于这两个页面属于不同的源,浏览器将会阻止此操作,并抛出一个跨源访问错误。
4 绕过同源策略的方法
尽管同源策略是一个强大的安全机制,但在实际开发中,有时需要跨源访问资源。为此,出现了一些绕过同源策略的方法,如:
4.1 JSONP(JSON with Padding)
JSONP 是一种通过动态 <script>
标签来进行跨域请求的技术。
<!DOCTYPE html>
<html>
<head>
<title>JSONP Example</title>
</head>
<body>
<script>
function handleResponse(data) {
console.log('JSONP response: ', data);
}
var script = document.createElement('script');
script.src = 'http://example.org/data?callback=handleResponse';
document.body.appendChild(script);
</script>
</body>
</html>
在此示例中,script
标签的 src
属性指向了跨域的资源,callback
参数指定了回调函数的名称。当请求成功时,返回的数据将会被传递给回调函数。
当然,如果你正在使用Vue或者React项目进行项目开发,推荐你读一读这篇博客,这是一个高效快捷使用JSONP的方法封装:前端JS必用工具【js-tool-big-box】,验证是否是Unicode字符,获取一个字符串的字节长度,以及新增发送JSONP跨域请求的方法-CSDN博客
4.2 CORS(Cross-Origin Resource Sharing)
CORS 是一种通过服务器设置 HTTP 头来允许跨域访问的方法。
服务器设置(Node.js 示例):
const express = require('express');
const app = express();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
app.get('/data', (req, res) => {
res.json({ message: 'This is a CORS-enabled response' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在此示例中,服务器通过设置 Access-Control-Allow-Origin
头来允许跨域访问。
5 最后
浏览器同源策略是 Web 安全的重要基石,尽管有时候它可能会限制开发者的操作,但其存在的主要目的是为了保护用户免受潜在的安全威胁。通过理解同源策略的工作原理和使用 JSONP 或 CORS 等技术,我们可以在保证安全的前提下实现跨域资源访问。