详细的跨域问题解决方案

本文详细介绍了四种跨域解决方案:1) JSONP,利用动态插入script标签实现GET请求的跨域;2) CORS,通过特定的HTTP头部设置允许跨域访问;3) Websocket,实现双向通信的跨域持久连接;4) Proxy,如Vue项目中的代理配置,以及服务器和Nginx的代理转发。每种方法都有其适用场景和优缺点。
摘要由CSDN通过智能技术生成

同源策略:

  • 协议相同(protocol)
  • 主机相同(host)
  • 端口相同(port)

如果不满足同源策略的网络请求就形成了跨域。

一.解决方案之 jsonp:

前端代码

showJsonp = function (obj) {
   console.log(obj)
}
// 回调函数拼在请求参数中
const url = 'http://localhost:3030/getTodoJsonp?callback=showJsonp'
// 利用script标签的src属性发起请求,解决跨域的问题,但仅限于get请求
const scriptEle = document.createElement('script')
scriptEle.setAttribute('src', url)
document.body.appendChild(scriptEle)
scriptEle.onload = function () {
   document.body.removeChild(scriptEle)
}

服务端代码(Node Express框架)

// 处理jsonp请求,解决跨域问题
app.get('/getTodoJsonp', function (req, res, next) {
  let callback = req.query.callback
  let content = callback + "({'message':'测试数据'})"
  res.send(content)
})

页面打印:{message: "测试数据"}

二.解决方案之CORS:

CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应

CORS 实现起来非常方便,只需要增加一些 HTTP 头,让服务器能声明允许的访问来源

只要后端实现了 CORS,就实现了跨域

后端代码栗子(Node Express框架)

// 设置允许跨域请求
app.all('*', function (req, res, next) {
  res.header('Access-Control-Allow-Origin', '*')
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
  res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
  res.header('X-Powered-By', '3.2.1')
  res.header('Content-Type', 'application/json;charset=utf-8')
  next()
})

Access-Control-Allow-Origin 设置为*其实意义不大,可以说是形同虚设,实际应用中,上线前我们会将Access-Control-Allow-Origin 值设为我们目标host

三.解决方案之Websocket:

Websocket 是 HTML5 的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。什么是全双工通信 ?简单来说,就是在建立连接之后,server 与 client 都能主动向对方发送或接收数据。我们这里以第三方库 ws 为例:

const WebSocket = require('ws');

const ws = new WebSocket('ws://www.host.com/path');

ws.on('open', function open() {
  ws.send('something');
});

ws.on('message', function incoming(data) {
  console.log(data);
});
... ...

需要注意的是,Websocket 属于长连接,在一个页面建立多个 Websocket 连接可能会导致性能问题。

四. 解决方案之Proxy:

代理(Proxy)也称网络代理,是一种特殊的网络服务,允许一个(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。一些网关、路由器等网络设备具备网络代理功能。一般认为代理服务有利于保障网络终端的隐私或安全,防止攻击

  1. vue项目开发过程可以配置vue.config.js文件来设置代理允许跨域。
// vue.config.js文件
module.exports = {
    devServer: {
        host: '127.0.0.1',
        port: 8080,
        open: true,// vue项目启动时自动打开浏览器
        proxy: {
            '/api': { // '/api'是代理标识,用于告诉node,url前面是/api的就是使用代理的
                target: "http://localhost:3030", //目标地址,一般是指后台服务器地址
                changeOrigin: true, //是否跨域
                pathRewrite: { // pathRewrite 的作用是把实际Request Url中的'/api'用""代替
                    '^/api': "" 
                }
            }
        }
    }
}

// axios发送请求中配置请求的根路径
axios.defaults.baseURL = '/api'
  1. 服务端实现代理请求转发

以express框架为例

var express = require('express');
const proxy = require('http-proxy-middleware')
const app = express()
app.use(express.static(__dirname + '/'))
app.use('/api', proxy({
  target: 'http://localhost:4000', 
  changeOrigin: false
}));
module.exports = app
  1. 通过配置nginx实现代理(一般用于生产环境中)
server {
		listen 8088;
		server_name 127.0.0.1; # 主机名
		gzip on;  # 开启gzip压缩功能
		gzip_min_length  1024; #设置最小压缩大小,单位字节
		gzip_types text/plain application/x-javascript text/css application/xml; #用来指定压缩的类型,“text/html”类型总是会被压缩。
		location / {
			root /home/exam/dist;
			index index.html index.htm;
			# 添加请求头
      add_header 'Access-Control-Allow-Origin' *;
      add_header 'Access-Control-Allow-Credentials' 'true';
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
		}

		location /api {
			include uwsgi_params;
      # 代理请求路径
			proxy_pass http://127.0.0.1:3033/api;
		}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值