关于cors:跨域问题解决办法

1次阅读

共计 1788 个字符,预计需要花费 5 分钟才能阅读完成。

什么是跨域?

同源策略 (Same-origin policy)

同源策略在 web 利用平安模型中是一个重要的概念。在这个策略下,浏览器容许第一个网页中蕴含的脚本能够获取第二个网页的数据,前提是这两个网页在同一个源下。

同源:须要 URI、主机名、端口都雷同。

这个策略能够避免一个网页上的歹意脚本通过 DOM 获取其余网页的敏感数据。

须要牢记的一点就是同源策略只利用于脚本,这意味着像 images、css 和其余动静加载的脚本 能够通过对应的标签跨域拜访资源。

CORS

跨域资源共享 Cross-origin resource sharing (CORS) 是一种机制,它应用额定的 HTTP 头来通知浏览器 让运行在一个 origin (domain) 上的 Web 利用被准许拜访来自不同源服务器上的指定的资源。

CORS 存在的意义

出于安全性,浏览器限度脚本内发动的跨源 HTTP 申请。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着应用这些 API 的 Web 应用程序只能从加载应用程序的同一个域申请 HTTP 资源,除非响应报文蕴含了正确 CORS 响应头。

跨源域资源共享(CORS)机制容许 Web 应用服务器进行跨源访问控制,从而使跨源数据传输得以平安进行。

理解了下面的内容,咱们解决浏览器控制台的跨域问题,个别有两个方向:

  1. 后端服务设置容许跨域拜访
  2. 前端通过代理拜访资源

服务端

用 Node.js 的一个框架 koa 来举例,解决跨域应用 koa-cors 非常简单,如下:

var koa = require('koa');
var route = require('koa-route');
var cors = require('koa-cors');
var app = koa();

app.use(cors());

app.use(route.get('/', function() {this.body = { msg: 'Hello World!'};
}));

app.listen(3000);

这个中间件大略做了这样的事件:

module.exports = () => {return async function(ctx, next) {ctx.set('Content-Type', 'application/json');
        ctx.set('Access-Control-Allow-Origin', '*');
        ctx.set('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE, PUT');
        ctx.set('Access-Control-Allow-Headers', 'X-Requested-With, content-type, X-Authorization, X-uuid');
        ctx.json = json.bind(ctx);
        ctx.halt = halt.bind(ctx);
        try {await next();
        } catch (e) {return ctx.halt(e.code, e.message);
        }
    };
};

这样前端收到的响应会是上面的样子:

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

本例中,服务端返回的 Access-Control-Allow-Origin: * 表明,该资源能够被 任意 外域拜访。

前端代理

如果应用了 webpack 那么配置一个代理就很容易,通过代理模拟出和服务端同源的申请。

//webpack.config.js
module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: {'^/api': ''},
      },
    },
  },
};

这样前端发动的申请蕴含 /api 的门路就会被代理到 http://localhost:3000,并且会把 /api 替换为空。如果你的接口地址原本就包含 /api,那只有把 pathRewrite: {‘^/api’: ”} 去掉即可。

更多高级性能可参考 官网

正文完
 0