首先想实现跨域先弄懂什么是跨域 所谓的跨域是建立在浏览器同源策越下对异源资源进行请求的行为
同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。
目前抛开只能跨域get请求的jsonp之外流行的两种跨域方式分别是
1 cors
CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。
也就是服务器运行进行跨域请求,因为要在服务端加上cors标识一般用于服务端进行跨域操作
2 代理 因为脚本不能请求异源资源,那么将脚本和资源服务器处于同一源即可。
cors相关方法
同源安全策略 默认阻止 “跨域” 获取资源。但是 CORS 给了web服务器这样的权限,即服务器可以选择,允许跨域请求访问到它们的资源。
所以既然是服务器选择开放的资源即可访问。所以根本原理便是在服务器的response上 加上表示可以访问资源的标识即可。
1 后端response拦截添加cors标识
比如各大node框架一般都自带跨域插件,如egg-cors,koa-cors之类的,当然也可以自己写插件进行response拦截。
'use strict';
module.exports = () => {
return async (ctx, next) => {
// 处理OPTIONS请求
if (ctx.method === 'OPTIONS') {
ctx.body = '';
}
ctx.set('Access-Control-Allow-Origin', '*');
// 设置所允许的HTTP请求方法
ctx.set('Access-Control-Allow-Methods', 'OPTIONS, GET, PUT, POST, DELETE');
// 字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段.
ctx.set('Access-Control-Allow-Headers', '*');
await next();
};
};
// add your middleware config here
config.middleware = [ 'httpError', 'cors' ];
2 通过第三方服务器为response添加上cors标识
以用nginx为例,用nginx代理资源服务器。然后在nginx内拦截response添加标识,再通过代理服务器去请求资源,nginx将自动为资源请求添加上cors标识
nginx.conf
server {
listen 9000;
server_name localhost;
location / {
proxy_pass http://localhost:8010; #代理的资源服务器
add_header 'Access-Control-Allow-Origin' $http_origin; # 全局变量获得当前请求origin,带cookie的请求不支持*
add_header 'Access-Control-Allow-Credentials' 'true'; # 为 true 可带上 cookie
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # 允许请求方法
add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers; # 允许请求的 header,可以为 *
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000; # OPTIONS 请求的有效期,在有效期内不用发出另一条预检请求
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204; # 200 也可以
}
}
}
代理
在开发环境我们的页面资源一般都挂载在开发服务器上,所以只需要在开发服务器上配置代理即可,如
webpack-dev-server 的 proxy设置
也可以直接用
express + http-proxy-middleware
其目的都是通过页面服务器去代替脚本资源去向资源服务器发起请求,因为服务器之间没有同源策略从而达到跨域的目的。
还有一种方法就是,第三方服务配置跨域,就是将脚本服务器和资源服务器都通过第三方服务器上,通过配置同一个域名的不同标识来识别访问。这样在浏览器看来他们都是统一域名下的资源了。 以 nignx为例
server {
listen 9001;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#页面服务
location / {
proxy_pass http://localhost:3000;
}
#接口服务
location ^~/apis/ {
rewrite ^/apis/(.*)$ /$1 break;
proxy_pass http://localhost:8010;
}
}