在Web开发中,跨域问题是一个常见的挑战。响应了解跨域详情的宝子 => 同源策略与跨域解决什么是同源与跨域? 本文将详细探讨几种常见的跨域解决方案,并分析它们的优缺点。
1. JSONP(JSON with Padding)
原理 :JSONP通过动态创建<script>
标签,利用src
属性不受同源策略限制的特性,实现跨域请求。
问题:
- 安全性问题 :由于JSONP依赖于
<script>
标签,容易受到XSS(跨站脚本攻击)的攻击。 - 请求方法限制:仅支持GET请求,无法使用POST等其他HTTP方法。
- 阻塞问题 :
<script>
标签的加载是宏任务,可能会阻塞页面渲染。 - 错误处理困难:如果请求失败,回调函数无法被调用,难以处理错误情况。
- 现代替代方案:随着CORS(跨域资源共享)的普及,JSONP已逐渐被淘汰。
2. CORS(跨域资源共享)
原理:CORS是一种W3C标准,允许服务器通过设置响应头来指定哪些源可以访问资源。
关键响应头:
Access-Control-Allow-Origin: *
:允许所有域名访问资源,或指定特定域名。Access-Control-Allow-Methods: GET, POST, PUT, DELETE
:指定允许的HTTP方法。Access-Control-Allow-Headers: Content-Type
:指定允许的请求头。Access-Control-Allow-Credentials: true
:允许跨域请求携带Cookie。Access-Control-Max-Age: 86400
:预检请求的缓存时间。
预检请求:
- 简单请求 :GET、POST、HEAD请求,且请求头为
Accept
、Accept-Language
、Content-Language
、Content-Type
(仅限于text/plain
、application/x-www-form-urlencoded
、multipart/form-data
)。 - 复杂请求 :也称预检请求,非简单请求会先发送OPTIONS预检请求,验证服务器是否允许该请求。
那问:GET 与 POST请求方式有什么区别?(文末给出答案)
3. WebSocket
原理:WebSocket是一种全双工通信协议,基于HTTP协议进行升级,默认支持跨域。
联想面题: (文末给出答案)
- webScoket 和webWorker 都是怎么实现的?都是 h5 新特性吗?
- http 1.0和2.0 有什么区别
特点:
- 无跨域问题:WebSocket协议本身不受同源策略限制。
- 双向通信:支持客户端和服务器之间的实时双向通信。
- 协议升级:通过HTTP协议进行握手,成功后升级为WebSocket协议。
示例代码:
javascript
体验AI代码助手
代码解读
复制代码
// 客户端
const ws = new WebSocket('ws://localhost:3000/ws');
ws.onopen = () => {
console.log('ws open');
ws.send('hello world');
};
ws.onmessage = (e) => {
console.log('ws onmessage', e.data);
};
// 服务器端
const WebSocket = require('ws');
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('websocket server\n');
});
const wss = new WebSocket.Server({ server, path: '/ws' });
wss.on('connection', (ws) => {
ws.on('message', (message) => {
console.log(`received: ${message}`);
ws.send(`server: ${message}`);
});
ws.send('server: hello');
});
server.listen(8080, () => {
console.log('server start');
});
4. postMessage
原理 :postMessage
是HTML5引入的API,允许不同源的窗口之间进行安全的消息传递。
应用场景:
- iframe嵌入:父页面与嵌入的iframe页面之间的通信。
- 跨域通信:不同域名下的页面之间进行数据传递。
示例代码:
html
体验AI代码助手
代码解读
复制代码
<!-- 父页面 -->
<body>
<h1>This is parent window</h1>
<input type="text" class="inp">
<button class="send">发送信息到iframe</button>
<div class="contents">
<p>接收到的信息</p>
<ul class="messages"></ul>
</div>
<iframe src="child.html" height="600" width="800" class="child-iframe" frameborder="0"></iframe>
<script>
window.addEventListener('message', (e) => {
console.log('接收到消息', e.data);
});
const win = document.querySelector('.child-iframe').contentWindow;
document.querySelector('.send').addEventListener('click', () => {
const message = document.querySelector('.inp').value;
win.postMessage(message, '*');
});
</script>
</body>
<!-- 子页面 -->
<h1>This is iframe child page.</h1>
<script>
window.addEventListener('message', (e) => {
window.parent.postMessage(e.data, '*');
});
</script>
5. Vite反向代理
原理:通过配置Vite的反向代理,将跨域请求转发到目标服务器,从而避免浏览器的同源策略限制。
配置示例:
javascript
体验AI代码助手
代码解读
复制代码
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'http://example.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^/api/, '')
}
}
}
};
回答前面面试问题:
1,get 和 post区别
- 功能:GET 请求主要用于从服务器获取数据,它是一种安全的方法,不会对数据进行修改或删除操作。POST 请求主要用于向服务器提交数据,以创建或更新资源
- 形式:get 请求通过URL 中的查询字符串(query string) 传递用户信息,数据会附加在请求的 URL 后面;post 请求则将用户信息包裹在请求体(request body)中进行传输。
- 安全:get 请求的参数会直接暴露在 URL 中,以明文形式展示,容易被截取或篡改,安全性较低;post 请求的参数放在请求体中,相对安全,但并非绝对安全,因为数据仍可能通过抓包等手段被截获。
- 信息量:get 请求的 URL 长度受到浏览器和服务器的限制,过长的参数可能会被截断,一般建议不超过 2KB; post 请求的请求体理论上可以传输大量数据,只要服务器能够处理,实际长度限制取决于服务器配置。
2,webSocket 和 webWorker 都是怎么实现的?都是 h5 新特性吗?
- WebSocket:WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它实现了浏览器与服务器之间的双向通信。WebSocket 的工作原理是先通过 HTTP 协议进行握手,建立连接后,服务器和客户端就可以通过 TCP 连接自由地发送数据。WebSocket 是 HTML5 开始广泛支持的一种技术,用于实现实时通信,如在线聊天、实时数据更新等功能。
- WebWorker:WebWorker 是一种允许多线程脚本并发运行的技术,它使网页能够在后台线程中运行脚本,而不会干扰用户界面的渲染和交互。WebWorker 创建一个独立的工作线程,用于处理耗时的操作,如复杂的计算、数据处理等。WebWorker 也是 HTML5 的新特性之一,用于提升网页的性能和响应速度。
3,http 1.0和2.0 有什么区别
- HTTP 1.0:HTTP 1.0 支持的请求方法主要包括 GET、HEAD(显示头部信息) 和 POST,每个请求都需要单独建立一个 TCP 连接 ,连接建立后只能顺序发送请求,无法同时发送多个请求,这会导致队头阻塞问题,即如果队列头部的请求没有完成,后续的请求就无法到达服务器。
- HTTP 2.0:HTTP 2.0 引入了多路复用 技术,允许多个请求和响应同时通过同一个 TCP 连接进行传输,从而解决了队头阻塞问题。它还采用了二进制分帧 的方式进行数据传输,将数据分割成更小的二进制帧,通过为每个帧分配独一无二的流标识符(ip流),实现传输过程中的断点续传功能。此外,HTTP 2.0 支持服务器推送(server push) ,服务器可以主动将资源推送给客户端,减少客户端的请求次数,提高页面加载速度。
总结
跨域问题是Web开发中的常见挑战,但通过合理选择和使用不同的跨域解决方案,可以有效解决这一问题。JSONP虽然简单,但存在安全性和功能上的局限性;CORS是现代Web开发中最常用的跨域解决方案;WebSocket适用于实时通信场景;postMessage
则适用于不同窗口或iframe之间的通信;Vite反向代理则提供了一种开发环境下的便捷解决方案。开发者应根据具体需求选择合适的跨域方案。