什么是跨域
如你们所知,出于安全考虑,浏览器会限制脚本中发起的跨站请求。好比,使用 XMLHttpRequest 对象发起 HTTP 请求就必须遵照同源策略(same-origin policy)。 具体而言,Web 应用程序能且只能使用 XMLHttpRequest 对象向其加载的源域名发起 HTTP 请求,而不能向任何其它域名发起请求。
解决策略
一、古老的jsonp方法(很麻烦须要先后端配合,并且只能用get方式)
二、反向代理(没用过,想了解的能够百度)
三、h5的CORS(很方便前端,由于这个是后端负责)
我只讲CORS(其它的另开篇幅)javascript
目前我在使用先后端分离的项目,而后就出现了跨域问题。先后端分离是大势所趋,跨域就显得尤其常见啊
在寻找跨域解决方案时,发现了最优雅解决方案就是HTML5来带了的“Cross-Origin Resource Sharing”的新特性,来赋予开发者权力决定资源是否容许被跨域访问。
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它容许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
只要服务器实现了CORS接口,就能够跨源通讯。html
你们看到没有,这是两个不一样的项目,一个跑在tomcat服务器下,一个在nginx服务器下。端口ip都不同,就产生了跨域前端
利用cors解决跨域
在后端,开启cors接口,容许跨域请求,前端就能够跨域了
只须要在springmvc的xml配置文件(默认为dispatcher-servlet.xml)加入这句就好了java
<!--path:容许请求的接口--> <!--origins:容许被哪些网站请求--> <!--methods:容许哪些http行为--> <mvc:cors> <mvc:mapping path="/**" allowed-origins="http://127.0.0.1:8020" allowed-methods="POST, GET, OPTIONS, DELETE, PUT" allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With" allow-credentials="true" /> </mvc:cors>
再看node
因此啊,跨域问题,面试官请不要老问咱们前端怎么解决,不少办法必须是后端配合或者是纯后端解决,咱们前端搞不了。
jsonp须要先后端配合,后端返回jsonp格式的数据,咱们前端根据商量好的函数名,来取
反射代理,彻底由后端作
cors,彻底由后端作,咱们浏览器开放了权限,但也不是咱们前端左右的
-----因此,不要再问咱们前端跨域怎么解决了,没有意义!!!!!-----nginx
cors跨域特殊说明面试
简单请求与复杂请求spring
说的cors跨域,还要作特殊说明:json
CORS能够分红两种:简单请求、复杂请求后端
一个简单的请求大体以下:
HTTP方法是下列之一
HEAD
GET
POST
HTTP头信息不超出如下几种字段
Accept Accept-Language Content-Language Last-Event-ID Content-Type,但仅能是下列之一 application/x-www-form-urlencoded multipart/form-data text/plain
任何一个不知足上述要求的请求,即被认为是复杂请求。
区别
复杂请求表面上看起来和简单请求使用上差很少,但实际上浏览器发送了不止一个请求。其中最早发送的是一种"预请求",我也叫它为探路,此时做为服务端,也须要返回"预回应"做为响应。预请求其实是对服务端的一种权限请求,只有当预请求成功返回,实际请求才开始执行。
因此看到复杂cors请求的时候都会看到两次请求,一次为opton,一次为真正的请求
nodejs作后端跨域设置例子
以上是以java为例子,全部的后端语言均可以设置这个,下边就拿node为例子【koa2框架】
const Koa=require ('koa'); const app=new Koa(); app.use(async (ctx, next) => { ctx.response.set('Access-Control-Allow-Origin', '*');//指定容许某域名访问:‘localhost:8080等等’ ctx.response.set('Access-Control-Allow-Methods', '*');//指定容许某方法访问:‘get、post等等’ ctx.response.set("Access-Control-Allow-Headers", "origin, content-type,token");//服务器支持的全部头信息字段.服务端一般是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析 if (ctx.request.method == "OPTIONS") { ctx.response.status = 200 }else{ await next(); } });
原生node
let http = require("http"); http.createServer(function () { response.writeHead(200,{ 'Access-Control-Allow-Origin':'*', 'Access-Control-Allow-Methods':'*' });//能够解决跨域的请求 response.write("Hello World\n"); response.end(); }).listen(8082);
参考有:
http://www.ruanyifeng.com/blog/2016/04/cors.html
http://www.poorren.com/cross-origin-resource-sharing-simple-complex