跨域解决方案及优劣

在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请求,且请求头为AcceptAccept-LanguageContent-LanguageContent-Type(仅限于text/plainapplication/x-www-form-urlencodedmultipart/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反向代理则提供了一种开发环境下的便捷解决方案。开发者应根据具体需求选择合适的跨域方案。

相关推荐
哀木1 小时前
一个简单的套壳方案,就能让你的 Agent 少做重复初始化
前端
问心无愧05131 小时前
ctf show web入门27
前端
小村儿1 小时前
给 AI Agent 装上"长期记忆":Karpathy 的 LLM Wiki 思想,我做成了工具
前端·后端·ai编程
竹林8181 小时前
用ethers.js连接MetaMask实现Web3钱包登录:从踩坑到稳定运行的完整记录
前端·javascript
heyCHEEMS1 小时前
如何用 Recast 实现静态配置文件源码级读写
前端·node.js
心连欣1 小时前
从零开始,学习所有指令!
前端·javascript·vue.js
review445432 小时前
大模型和function calling分别是如何工作的
前端
东东同学2 小时前
耗时一个月,我把 Nuxt 首屏性能排障经验做成了一个 AI Skill
前端·agent
冴羽3 小时前
超越 Vibe Coding —— AI 辅助编程指南
前端·ai编程·vibecoding
梦想的颜色3 小时前
一天一个SKILL——前端最佳自动化测试 webapp-testing
前端·web app