NO.14 跨域解决方案

跨域在网上的定义是:跨域是指一个域下的文档或脚本试图去请求另一个域下的资源

常见的是有多个服务器然后请求数据,所以需要发起跨域请求前端是8080,后端是3000所以需要解决前后端的跨域问题

网上常见的方法是通过jsonp跨域

缺点:容易被攻击,只能实现get请求

通过标签允许跨域的的原理所以可以通过动态创建script来进行跨域

JSONP由回调函数和数据组成,回调函数是当响应到来时应该在页面中调用的函数,回调函数的名称一般是在请求中指定的,而数据就是传入回调函数中的JSON数据

<script>
    var script = document.createElement('script');
    script.type = 'text/javascript';

    // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
    document.head.appendChild(script);

    // 回调执行函数
    function handleCallback(res) {
        alert(JSON.stringify(res));
    }
 </script>
1
2
3
4
5
6
7
8
9
10
11
12
13

源自:安静de沉淀

<script>
    function test(json) {
        console.log('我被调用了');
        console.log(json);
    }
</script>
<script src="http://api.douban.com/v2/movie/top250?callback=test"></script>
1
2
3
4
5
6
7

源自Mr_桐先生

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)

在后端创建middlewares层放置cors文件

const cors = {
    allowAll:function(req,res,next){
      res.header("Access-Control-Allow-Headers", "*");
      res.header("Access-Control-Allow-Origin", req.headers.origin);
      res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS');
      res.header('Access-Control-Allow-Credentials', true);
      next();
    }
  }
  
  module.exports = cors;
1
2
3
4
5
6
7
8
9
10
11

Access-Control-Allow-Credentials 该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。

如果需要发送cookie 那么Access-Control-Allow-Origin就不能设置为*号必须指定明确的、与请求网页一致的域名。

Access-Control-Allow-Methods 该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。

Access-Control-Allow-Headers 字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。

在使用到的地方引入文件例如api.js

var cors = require('./../middlewares/cors.js');

router.post('/login',cors.allowAll,authController.login);
1
2
3

还有打包好的cors

npm install cors
1

简单引入开启全部cors

var express = require('express')
var cors = require('cors')
var app = express()
 
app.use(cors())
 
app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})
 
app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})
1
2
3
4
5
6
7
8
9
10
11
12
13

单个使用方式

app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})
1
2
3

参考资料:http://www.ruanyifeng.com/blog/2016/04/cors.html