跨域资源请求 JSONP CORS
1.什么是跨域资源请求?
如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。
1.1 同源策略
浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。用于隔离潜在恶意文件的重要安全机制。
1.1.1 同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。
使用js脚本读写非同源的资源会被拒绝的(跨域资源的引入是可以的,使用js读写则受限制),因此 xmlhttprequest 受同源策略限制。
1.1.2 跨域的安全限制都是对浏览器端来说的,服务器端是不存在跨域安全限制。
1.2 不受同源策略限制的
1.2.1 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。(跨域资源的引入是允许的)
如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。
2.如何解决 跨域资源请求 限制
jsonp https://blog.csdn.net/dff1993/article/details/79925874
cors
2.1 jsonp (不推荐)
利用 <script src="..."></script> 中src不受同源策略限制实现跨域资源访问
例子:跨域资源位于 http://localhost:8066/file/jsonp
## springboot 工程
@requestmapping(value="/jsonp", method=requestmethod.get ) public string jsonp(@requestparam("callback") string callback, httpservletrequest request) { // 处理正确的jsonp请求, 返回: callback方法名(json字符串) if(callback != null && !callback.equals("")) { return callback + "(" + "{\"key\": \"hello\"}" + ")"; } //不是jsonp请求 return "hello"; }
2.1.1 使用ajax出现 跨域请求限制
### xmlhttprequest发起了请求,但是响应中获取不到值
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>ajax 跨域请求(不能成功)</title> </head> <body> <div id="mydiv"> <button id="btn">点击</button> </div> </body> <script type="text/javascript"> window.onload = function() { var obtn = document.getelementbyid('btn'); obtn.onclick = function() { var xhr = new xmlhttprequest(); xhr.onreadystatechange = function() { if (xhr.readystate == 4 && xhr.status == 200) { // 处理响应 alert( xhr.responsetext ); } }; // 跨域请求 xhr.open('get', 'http://localhost:8066/file/jsonp?callback', true); xhr.send(); }; }; </script> </html>
2.1.2 使用jsonp 避免跨域请求限制
## # 在页面插入带有src 属性的 <script>标签,src 地址即跨域资源地址(只能是get请求);
### 服务端对于 jsonp请求的 响应格式是: callback函数名(json字符串)
浏览器收到响应后,执行回调函数处理响应。
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>jsonp实现跨域(只支持get请求)</title> </head> <body> <div id="mydiv"> <button id="btn">点击</button> </div> </body> <script type="text/javascript"> // 回调函数,处理响应 function handleresponse(response){ console.log(response); alert(json.stringify(response)); //将json对象转为 字符串 } </script> <script type="text/javascript"> window.onload = function() { var obtn = document.getelementbyid('btn'); obtn.onclick = function() { // 创建一个script标签 var script = document.createelement("script"); //设置script标签的src script.src = "http://localhost:8066/file/jsonp?callback=handleresponse"; //在页面插入一个script标签,将会发起src请求 document.body.insertbefore(script, document.body.firstchild); }; }; </script> </html>
#####
2.2 cors (推荐)
cors是一个w3c标准,全称是"跨域资源共享"(cross-origin resource sharing)。它允许浏览器向跨源服务器,发出xmlhttprequest
请求,从而克服了ajax只能使用的限制。
cors需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,ie浏览器不能低于ie10。
整个cors通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,cors通信与同源的ajax通信没有差别,代码完全一样。浏览器一旦发现ajax请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现cors通信的关键是服务器。只要服务器实现了cors接口,就可以跨源通信。
ps: cookie 依然遵循“同源策略”,只有用目标服务器域名设置的 cookie 才会上传,而且使用 document.cookie
也无法读取目标服务器域名下的 cookie。
### 例如 : 支持跨域请求
响应头中含有 access-control-allow-origin ; 它的值要么是请求时origin
字段的值,要么是一个*
,表示接受任意域名的请求。
2.2.1 springboot 后台服务 配置 支持 cors
## 配置 webmvcconfigureradapter
## 增减配置后,则可提支持 站外ajax请求访问的跨域资源
2.2.1.1 配置后台服务
import org.springframework.context.annotation.configuration; import org.springframework.web.servlet.config.annotation.corsregistry; import org.springframework.web.servlet.config.annotation.webmvcconfigureradapter; @configuration public class corsconfiguration extends webmvcconfigureradapter { @override public void addcorsmappings(corsregistry registry) { registry.addmapping("/**") .allowedmethods("*") .allowedorigins("*") .allowedheaders("*"); } }
addmapping:配置可以被跨域的路径,可以任意配置,可以具体到直接请求路径。
allowedorigins:允许所有的请求域名访问我们的跨域资源,可以固定单条或者多条内容,如:"http://www.baidu.com",只有百度可以访问我们的跨域资源。
allowedheaders:允许所有的请求header访问,可以自定义设置任意请求头信息,如:"x-yauth-token"
2.2.1.2 可以直接使用 xmlhttprequest 访问跨域资源
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>ajax 跨域请求</title> </head> <body> <div id="mydiv"> <button id="btn">点击</button> </div> </body> <script type="text/javascript"> window.onload = function() { var obtn = document.getelementbyid('btn'); obtn.onclick = function() { var xhr = new xmlhttprequest(); xhr.onreadystatechange = function() { if (xhr.readystate == 4 && xhr.status == 200) { // 处理响应 alert( xhr.responsetext ); } }; // 跨域请求 xhr.open('get', 'http://localhost:8066/file/jsonp?callback', true); xhr.send(); }; }; </script> </html>
3. 跨域请求伪造 csrf 防御
cors - cross origin resourse-sharing - 跨站资源共享
csrf - cross-site request forgery - 跨站请求伪造
3.1 如何防止 csrf 攻击
csrf 攻击:
当用户不小心在本机访问 fuck.com
黑客页面的时候,黑客页面上放了一个按钮或者一个表单(url/action 为 http://you.com/delete-myself,当前用户登录过的网站),
当用户触发这个按钮或表单的,浏览器发出 get 或 post 请求的时候,会带上 you.com
的 cookie;如果you.com网站没有做 csrf 防御措施,那么这次请求在 you.com
看来会是完全合法的,但是实际上是黑客伪造的请求。
csrf 防御:
csrf 主流防御方式是,用户登录后在后端生成随机 token,将此串 token 返回到客户端保存到cookie中。用户之后的每个请求都会携带cookie,如果后端检查到没有 token,则请求失败。
由于cookie受同源限制,从黑客页面(fuck.com
)发起的请求获取不到用户网站(you.com
)的cookie,因此伪造的请求无法通过后端的检验,请求将无效。 ??
即使cookie被劫持,可以在后台增减对 cookie校验(在cookie中添加校验信息,这个校验信息和当前用户外置环境有些关系,比如ip,useragent等有关)。??
4. xss 跨站点脚本攻击
上一篇: 屏蔽机器人从你的网站搜取email地址的php代码
下一篇: 用户,组及权限