前端跨域的解决方案

655 阅读2分钟

一 什么是跨域

1:浏览器使用ajax时,如果请求的接口地址和当前开的页面地址不同源称之为跨域。

跨域的报错格式

1111.png

二 为什么产生跨域

是因为浏览器的同源安全策略引起的,浏览器认为两个地址不一样,浏览器认为不是一家的,所以就阻止两个地址的请求,那什么是同源就是两个地址协议主机端口均一致

三 解决跨域方案

第一种:CORS

目前的主流方案,也是最简单的方案,直接让后端设置相应头,允许资源共享

注:这种解决方式是交给后端解决的,前端无法操作。

//Access-Control-Allow-Origin意思告诉服务器,任何地址都可以访问
// 创建一个 CORS 中间件 
function allowCrossDomain(req, res, next) { 
  res.header('Access-Control-Allow-Origin', 'http://example.com'); 
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 
  res.header('Access-Control-Allow-Headers', 'Content-Type'); 
  next(); 
}

//...

app.configure(function() { 
  // ...
  
  // 为 Express 配置 CORS 中间件
  app.use(allowCrossDomain); 
  
  // ...
});

1571858546263.png

第二种:JSONP

曾经的跨域杀手,专治各总跨域问题,现在慢慢的淡出历史舞台,JSOP是前后端配合来使用。 他的原理就是:通过动态创建script标签,通过script标签的src发请求,没有跨域限制来获取资源。

1:JSOP只能用get请求,因为get请求参数直接写url拼接,而post请求参数是放在请求体中的

2:callback没官方规定,只是程序员约定俗成的jsop键值名

前端获取

<!-- 前端页面 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
    function fn(obj){
console.log(obj);
    }

    </script>
    <!-- callback传值 -->
    <script src="http://127.0.0.1:8077/getlist?callback=fn"></script>
    
</body>
</html>
    

服务器

// 服务器页面

// 导入模块
const express=require('express')
// 创建服务器
const app=express()
// 写接口
app.get('/getlist',(req,res)=>{
    res.send(`${req.query}({name:"小明",age:"18岁",hook:"打球"})`, )
})
// 开启服务器

app.listen(8077,()=>{
    console.log("服务器开始,端口号是8077....");
})

11111.png

3333.png

第三种:中间件代理服务器

说明: 同源策略, 是浏览器的安全策略, 服务器于服务器之间, 没有跨域问题! 所以可以利用代理服务器转发请求!

  1. 开发环境的跨域问题 (使用webpack代理服务器解决)

    配置 devServer 的 proxy 配置项

module.exports = {
  devServer: {
   // 代理配置
    proxy: {
        // 这里的api 表示如果我们的请求地址有/api的时候,就出触发代理机制
        '/api': {
          target: 'www.baidu.com', // 我们要代理请求的地址
           // 路径重写
          pathRewrite: {
              // 路径重写  localhost:8888/api/login  => www.baidu.com/api/login
              '^/api': '' // 假设我们想把 localhost:8888/api/login 变成www.baidu.com/login 就需要这么做 
          }
      },
    }
  }
}

2.生产环境的跨域问题,Nginx反向代理配置 解决生产环境跨域