前后端分离开发中的跨域问题解决方案

1. 前后端分离开发

为了适应软件开发工程化趋势的要求, 目前越来越多的公司开始采用"前后端分离"的开发模式,这样开发的好处很多, 比如开发人员的分工更加细化,便于提供开发效率等. 但是只要采用了前后端分离的开发模式, 那么在请求后端数据时, 都会遇到跨域的问题.

1.1. 跨域问题的本源

跨域,是指浏览器不能执行其它网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript实施的安全限制。
所谓同源,就是域名、协议、端口均相同。举个例子:

http://www.123.com/index.html 调用 http://www.123.com/abc.do (非跨域)
http://www.123.com/index.html 调用 http://www.456.com/abc.do (主域名不同:123/456,跨域)
http://abc.123.com/index.html 调用 http://def.123.com/server.do (子域名不同:abc/def,跨域)
http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.do(端口不同:8080/8081,跨域)
http://www.123.com/index.html 调用 https://www.123.com/server.do (协议不同:http/https,跨域)

1.2. 实际开发中跨域问题解决:

在实际开发中遇到的跨域问题大致分为两类:

  • 开发人员前端和后端都可以控制, 那么这种情况下, 解决跨域问题既可以采用后端解决, 也可以采用前端解决;
  • 开发人员只能控制前端, 后端是调用别人已经开发部署的资源. 这种情况下, 只能通过前端来解决跨域问题.

本文以目前比较流行的前后端分离开发方案–Vue + Django, 分别给出跨域问题的解决方案.

2. 跨域问题的解决方案

随着互联网的发展,同源策略严重影响了项目之间的连接,尤其是大项目,需要多个域名配合完成,因此W3C推出了CORS,即Cross-origin resource sharing(跨来源资源共享)。CORS的基本思想就是使用额外的HTTP头部让浏览器与服务器进行沟通,从而决定是否接受跨域请求。

CORS需要浏览器和服务器同时支持,目前,所有浏览器都支持该功能。对于开发者来说,CORS通信与同源的AJAX通信没有区别,代码完全一样。浏览器在跨域访问时,会自动添加HTTP头信息,或者发起预检请求,用户对此毫无感知。因此是否支持跨域请求,关键在于服务器是否做了CORS配置,允许跨域访问。

因此, 所谓的前端解决方案, 本质是做的一层代理.

2.1. 服务端解决方案

服务端使用Django+ restframework提供项目API接口. 在解决跨域问题时按照如下处理:

  1. 安装 django-cors-headers, 在命令行终端使用pip工具完成
pip install django-cors-headers -i https://pypi.tuna.tsinghua.edu.cn/simple
  1. 对项目进行设置, 在项目的settings中进行
  • 添加应用, 找到INSTALLED_APPS, 添加corsheaders, 代码如下:
INSTALLED_APPS = [
  'django.contrib.admin',
  'django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.messages',
  'django.contrib.staticfiles',
  'rest_framework',
  'corsheaders',
  'home',
]
  • 添加中间件, 找到MIDDLEWARE, 添加CorsMiddleware, 注意一定要写在所有中间件的头部:
MIDDLEWARE = [
  'corsheaders.middleware.CorsMiddleware',
  'django.middleware.security.SecurityMiddleware',
  'django.contrib.sessions.middleware.SessionMiddleware',
  'django.middleware.common.CommonMiddleware',
  'django.middleware.csrf.CsrfViewMiddleware',
  'django.contrib.auth.middleware.AuthenticationMiddleware',
  'django.contrib.messages.middleware.MessageMiddleware',
  'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
  • 开启跨域接受跨域请求, 添加白名单. 添加如下设置:
CORS_ALLOW_CREDENTIALS = False
CORS_ORIGIN_ALLOW_ALL = True

完成上述模块安装和项目配置后, 跨域问题服务端就解决了, 这个服务器可以接收任何前端应用的数据访问请求.

2.2. 前端的解决方案

当前端采用Vue框架进行开发时, 如果服务端我们没有办法控制, 就只能从前端着手进行解决.

  1. 在vue项目根目录下建立vue.config.js文件.代码如下:
module.exports={
  devServer:{
    host:'0.0.0.0',
    port:8081,
    // 跨域解决
    proxy:{
      '/api':{
        target:"https://www.csdn.net/",
        changeOrigin:true,
        ws:true,
        secure:false,
        pathRewrite:{
          '^/api':'/api'
        }
      }
    }
  }
}

配置完成后要重启本地服务器.
2. 使用实例
使用axios发起网络数据请求, 首先要安装:

cnpm install axios --save

安装完成后, 在src目录添加network文件夹, 在其中新建request.js, 封装网络数据请求:

import axios from 'axios'

export function request(config){
  const instance = axios.create({
    baseURL:'/api'
  })
  return instance(config)
}

因为完整的csdn的API接口地址为:https://www.csdn.net/api/articles?type=more&category=home&shown_offset=1524276761019196&first_view=false. 所以在baseURL:'/api'.
3. 在使用数据的组件页面调用代码
经过封装的request.js在需要数据请求的组件中就可以直接调用.示例代码如下:

<script>
import {onMounted, reactive} from 'vue'
import {request} from "@/network/request";

export default {
  name: 'Home',
  setup(){
    const state=reactive({
      result:null
    })
    onMounted(()=>{
      request({
        url:'/articles?type=more&category=home&shown_offset=1524276761019196&first_view=false'
      }).then(res=>{
        console.log(res);
      })
    })
    return {state}
  }
}
</script>

注意: vue3.0开始启用组合式API, 组件数据请求应该放置在生命周期函数onMounted中完成.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值