Http系列-07-cors跨域解决方案

266 阅读2分钟

1.跨域例子:

先来看下目录结构:这里就不多做介绍了

03-cors跨域             
├─ index.html         
├─ package-lock.json  
├─ package.json       
└─ server.js          

1.接着来看下发生跨域的代码:

//index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <script src='/axios/dist/axios.js'></script>
  <h2>CORS跨域</h2>
  <script>
    axios.defaults.baseURL = 'http://127.0.0.1:3002';
//发送post请求,这里没有加参数
    axios.post('/login')
      .then(res => {
        console.log(res);
      }).catch(err => {
        console.log(err);
      })
  </script>
</body>
</html>

2.接着来看下server.js中的代码:

//server.js

const express = require('express');
const fs = require('fs');
const app = express();
// 中间件方法
// 设置node_modules为静态资源目录
// 将来在模板中如果使用了src属性 http://localhost:3000/node_modules
app.use(express.static('node_modules'))
//设置允许跨域访问该服务.
app.get('/',(req,res)=>{
  fs.readFile('./index.html',(err,data)=>{
    if(err){
      res.statusCode = 500;
      res.end('500 Interval Serval Error!');
    }
    res.statusCode = 200;
    res.setHeader('Content-Type','text/html');
    res.end(data);
  })
})

app.post('/login',(req,res)=>{
  // 如果获取post请求中请求体的数据
  console.log(req.body)

  res.json({status:0,message:'登录成功'})
})
app.listen(3002);

会出现如下图跨域结果:

3.通过cors解决跨域

🤪server.js代码如下:

const express = require('express');
const fs = require('fs');
const app = express();

//🌵设置允许跨域访问该服务.
app.all('*', function (req, res, next) {
  
  // 🏖允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'
  
  res.header('Access-Control-Allow-Origin', 'http://localhost:3002');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  //允许令牌通过
  res.header('Access-Control-Allow-Headers', 'Content-Type,X-Token');
  res.header('Access-Control-Allow-Methods', '*');
  // 允许携带cookie
  res.header('Access-Control-Allow-Credentials', 'true');
  res.header('Content-Type', 'application/json;charset=utf-8');
  next();
});

// 中间件方法
// 设置node_modules为静态资源目录
// 将来在模板中如果使用了src属性 http://localhost:3000/node_modules
app.use(express.static('node_modules'))
//设置允许跨域访问该服务.
app.get('/',(req,res)=>{
  fs.readFile('./index.html',(err,data)=>{
    if(err){
      res.statusCode = 500;
      res.end('500 Interval Serval Error!');
    }
    res.statusCode = 200;
    res.setHeader('Content-Type','text/html');
    res.end(data);
  })
})
// app.set('jsonp callback name', 'cb')

app.post('/login',(req,res)=>{
  // 如果获取post请求中请求体的数据
  console.log(req.body)

  res.json({status:0,message:'登录成功'})
})
app.listen(3002);

结果如下图:

4.如果想要携带token呢?

解决办法如下:

//index.html
<!DOCTYPE html>
...
<body>
  <script src='/axios/dist/axios.js'></script>

  <h2>CORS跨域</h2>
  <script>
    axios.defaults.baseURL = 'http://127.0.0.1:3002';
    axios.post('/login',
    {
        username: '醉翁之意不在酒',
        password: 123321
      }, {
        headers: {
          // 'Authorization': 'getElementByYouHeart'
          "X-Token":"gogoing" //token
        },
        //可以看axios文档: 表示跨域请求时需要使用凭证 允许携带cookies
        withCredentials: true
      }
      )
      .then(res => {
        console.log(res);
      }).catch(err => {
        console.log(err);
      })
  </script>
</body>
...
...省略...
//设置允许跨域访问该服务.
app.all('*', function (req, res, next) {
  /// 允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'
  res.header('Access-Control-Allow-Origin', 'http://localhost:3002');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  //🌵允许令牌通过(携带token的时候必须写这个)
  res.header('Access-Control-Allow-Headers', 'Content-Type,X-Token');
  res.header('Access-Control-Allow-Methods', '*');
  //🌵允许携带cookie携带
  res.header('Access-Control-Allow-Credentials', 'true');
  res.header('Content-Type', 'application/json;charset=utf-8');
  next();
});
...
...省略...

结果如下:

5.通过cors解决跨域问题:

需要安装cors来解决跨域(npm i cors -S)

//index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src='/axios/dist/axios.js'></script>
  <script src="https://cdn.bootcss.com/qs/6.9.1/qs.js"></script>
  <h2>CORS跨域</h2>
  <script>
    axios.defaults.baseURL = 'http://127.0.0.1:3002';

    axios.post('/login',
    {
        username: '醉翁之意不在酒',
        password: 123321
      }, {
        headers: {
          'Authorization': 'getElementByYouHeart'
        },
        //可以看axios文档: 表示跨域请求时需要使用凭证 允许携带cookies
        withCredentials: true
      }
      )
      .then(res => {
        console.log(res);
      }).catch(err => {
        console.log(err);

      })
  </script>
</body>
</html>

接下来是server.js

//server.js

const express = require('express');
const fs = require('fs');
const app = express();
const cors = require('cors');

// 设置cors中间件 允许跨域访问

app.use(cors({
  origin:'http://localhost:3002',
  credentials:true,
  methods:['GET','POST'],
  allowedHeaders:'Content-Type,Authorization'
}))

// 中间件方法
// 设置node_modules为静态资源目录
// 将来在模板中如果使用了src属性 http://localhost:3000/node_modules
app.use(express.static('node_modules'))
//设置允许跨域访问该服务.
app.get('/',(req,res)=>{
  fs.readFile('./index.html',(err,data)=>{
    if(err){
      res.statusCode = 500;
      res.end('500 Interval Serval Error!');
    }
    res.statusCode = 200;
    res.setHeader('Content-Type','text/html');
    res.end(data);
  })
})
// app.set('jsonp callback name', 'cb')

app.post('/login',(req,res)=>{
  // 如果获取post请求中请求体的数据
  console.log(req.body)

  res.json({status:0,message:'登录成功'})
})
app.listen(3002);