常见3种跨域解决方法

124 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

  1. 什么是跨域?

跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。

同源策略限制以下行为:

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM 和 JS 对象无法获取
  • Ajax请求发送不出去
  1. 解决跨域的方法(3种)
  • JSONP
  • 后端解决( CROS)
  • 前端解决(前后端--Vue等)

JSONP

  • 普通请求值 XHR,希望得到服务端返回的 content-type 一般是 json
  • JSONP 发出的是 script 请求,希望得到的返回是 js 脚本
JSONP原理:
发送 ajax 请求的时候,设置dataType:"jsonp",将使用 JSONP 方式调``用函数,
函数的 url 变为myurl?callback=e5bbttt的形式,
根据一个临时方法名,后端会根据callback的值返回一个 js 脚本
JSONP弊端:
1. 需要服务器改动代码
2. 只支持 GET 请求
3. 发送的不是 xhr 请求
4. 不安全

CROS(用于后端解决跨域问题)

  • webConfig.java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 允许跨域的访问路径
                .allowedOrigins("*")  // 允许跨域访问的源(例如:http://localhost:8080)
                .allowedHeaders("*") // 允许所有的请求header访问
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 允许请求方法
                .maxAge(3600) // 预检间隔时间
                .allowCredentials(true); // 是否允许发送 cookie
    }

}

如说使用发的是前后端开发(例如VUE等),为了方便开发不用每次写全域名还需要在axios中作如下配置:

  • axios.js
'use strict'

import Vue from 'vue'
import axios from 'axios'

const config = {
  baseURL: 'http://localhost:8081',  //设置根地址(即服务器的地址,为了方便以后直接用‘/’代替==>重点)
  timeout: 60 * 1000, // 超时设置
  withCredentials: true, // 检查跨站点访问控制
  changeOrigin: true  //允许跨域
}

const _axios = axios.create(config)

_axios.interceptors.request.use(
  function (config) {
    return config
  },
  function (error) {
    return Promise.reject(error)
  }
)

_axios.interceptors.response.use(
  function (response) {
    return response
  },
  function (error) {
    return Promise.reject(error)
  }
)

Plugin.install = function (Vue, options) {
  Vue.axios = _axios
  window.axios = _axios
  Object.defineProperties(Vue.prototype, {
    axios: {
      get () {
        return _axios
      }
    },
    $axios: {
      get () {
        return _axios
      }
    }
  })
}

Vue.use(Plugin)

export default Plugin

Proxy(代理方式)

  • vue.config.js
module.exports = {
  lintOnSave: false,
  devServer: {
    host: 'localhost',  //前端地址
    port: 8084,  //前端端口号
    proxy: {
      '/': {  //将http://localhost:8081用/代替
        target: 'http://localhost:8081',  //远程服务器地址
        changeOrigin: true,
       //这个设置可有可无  看需求而定
       //pathRewrite: {
       //'^/reagent': '/'  //相当于把/reagent用‘/’来代替
       // }
      }
    }
  }
}

test.vue

<template>
  <div>
    <el-button type="success" @click="getValue">测试</el-button>
  </div>
</template>

<script>
export default {
  name: 'test',
  methods: {
    getValue () {
    // 这里的'/'代表的是'http://localhost:8081',最后的访问路径为'http://localhost:8081/logincheck'
      axios.get('/logincheck').then((res) => {
        this.$message({
          type: 'success',
          message: res.data
        })
      }).catch((err) => {
        this.$message({
          type: 'warning',
          message: err.message()
        })
      })
    }
  }
}
</script>

<style scoped>

</style>