阅读 209

前端基础:如何解决跨域问题

同源策略

同源策略是跨域问题的根本所在。

同源的“源”代表 origin,同源就表示两个 URL 的 origin 是相同的,originprotocolhostport 组成。

{   "protocol": "http:",   "host": "web.example.com",   "port": "",   "origin": "http://web.example.com" } 复制代码

同源策略是一个非常重要的安全策略,它用于限制两个源之间在浏览器上进行资源交互。如果缺少了同源策略,网站或服务器很容易受到 XSS、CSFR 等攻击。

方案一(最直接):设置 CORS 跨域资源共享

设置 CORS 是最直接的方法。该方案无需前端操作,只需后端在返回响应时设置响应头即可:

{   "Access-Control-Allow-Origin": "http://web.domain.com" // 指定允许访问的域名 || 通配符 * 表示所有网站都可以访问资源 } 复制代码

方案二(最兼容):使用 Nginx 反向代理

同源策略是浏览器需要遵循的标准,而服务器之间的交互无需遵循同源策略。

使用 Nginx 作为 Web 服务器,监听并接收来自外部(其他服务器)请求,将接收到的请求使用和本机相同的域名转发到后端,然后再将响应返回给前端。

使用 Nginx 反向代理的必要设置如下:

// nginx.conf server {   listen 80;   server_name web.domain.com;   location / {       proxy_pass server.domain.com;   } } 复制代码

修改后需要重启 Nginx 服务器:

sudo nginx -s reload 复制代码

方案三(最方便):前端使用 Webpack 代理

同样也是利用服务器向服务器请求无需遵循同源策略的特点。只不过这里我们使用 Webpack 作为代理服务器。

该方案无需后端操作,只需在 webpack.config.js 中配置即可:

// webpack.config.js module.exports = {   devServer: {     proxy: {       // 接口前缀       "/api": {         target: "http://server.domain.com", // 指定服务器地址       },     },   }, } 复制代码

方案四(最古老):使用 JSONP

JSONP(JSON with Padding)主要是利用 <script> 标签加载脚本不受同源策略的限制这一特性,来加载需要请求的资源。

该方法需要后端和前端同时设置,且仅支持 GET 请求。

后端代码示例(以 node.js 为例):

const querystring = require("querystring") const http = require("http") const server = http.createServer() server.on("request", function (req, res) {   const params = qs.parse(req.url.split("?")[1])   const fn = params.callback   res.writeHead(200, { "Content-Type": "text/javascript" }) // 设置返回的 MIME 类型为 text/javascript   res.write(fn + "(" + JSON.stringify(params) + ")") // 回调函数   res.end() }) server.listen("8080") 复制代码

前端代码示例:

let script = document.createElement("script") // 在 URL 后指定一个回调函数 script.src = "http://server.domain.com/api/list?callback=handleCallback" document.head.appendChild(script) // 回调执行函数 function handleCallback(res) {   console.log(res) } 复制代码

方案五(最新):使用 WebSocket

HTML5 定义了 Websocket 协议,该协议主要用于服务器和浏览器之间的持久化连接,并且没有同源策略的限制。

该方案需要后端提供 Websocket 接口,前端进行接收。

前端代码示例:

let ws = new WebSocket("ws://server.domain.com/api/list") ws.onopen = function () {   console.log("连接成功") } ws.onmessage = function (res) {   console.log(res.data) } ws.onclose = function () {   console.log("连接关闭") } 复制代码

后端代码示例(以 node.js 为例):

const WebSocket = require("ws") const server = new WebSocket.Server({ port: 8080 }) server.on("connection", function (socket) {   socket.on("message", function (data) {     socket.send(data)   }) }) 复制代码

如果仅仅是为了实现跨域,不推荐使用 Websocket。


作者:李麦麦
链接:https://juejin.cn/post/7034789106387255333


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐