资讯专栏INFORMATION COLUMN

004. 前端跨域资源请求: JSONP/CORS/反向代理

番茄西红柿 / 1314人阅读

摘要:同源策略浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。不受同源策略限制的跨域资源的引入是允许的页面中的链接,重定向以及表单提交是不会受到同源策略限制的。

1.什么是跨域资源请求?

https://www.cnblogs.com/niuli1987/p/10252214.html

同源: 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。

 

1.1 同源策略 : 浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。用于隔离潜在恶意文件的重要安全机制。

同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。

使用js脚本读写非同源的资源会被拒绝的(跨域资源的引入是可以的,使用js读写则受限制),因此 XMLHttpRequest 受同源策略限制。

 

1.2 不受同源策略限制的(跨域资源的引入是允许的)

1.2.1 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。

如嵌入到页面中的 script src="..." /script , img , link , iframe 等。

 

 ps: 跨域限制都是对浏览器端来说的,服务器端是不存在跨域安全限制。

 

 

2.如何解决 跨域资源请求 限制 JSONP  https://blog.csdn.net/DFF1993/article/details/79925874 CORS http://www.ruanyifeng.com/blog/2016/04/cors.html

2.1 JSONP (不推荐)

例子:跨域资源位于  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 避免跨域请求限制

原理:利用  script src="..." /script 中src 引入跨域资源(不受同源策略限制),浏览器收到响应后,通知回调函数处理该跨域资源。

缺点:只能通过是get请求引入跨域资源。

### 在页面插入带有src 属性的 script 标签,src 地址即跨域资源地址;

### 服务端对于 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。

 

### 例如 : https://api.github.com/  支持跨域请求

响应头中含有   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;

 

addMapping:配置可以被跨域的路径,可以任意配置,可以具体到直接请求路径。

allowedMethods:允许所有的请求方法访问该跨域资源服务器,如:POST、GET、PUT、DELETE等。
allowedOrigins:允许所有的请求域名访问我们的跨域资源,可以固定单条或者多条内容,如:"http://www.baidu.com",只有百度可以访问我们的跨域资源。
allowedHeaders:允许所有的请求header访问,可以自定义设置任意请求头信息,如:"X-YAUTH-TOKEN"

 

      2.3 利用nginx 反向代理解决跨域问题   https://www.cnblogs.com/bninp/p/5694277.html

location /apis {
rewrite ^.+apis/?(.*)$ /$1 break;
include uwsgi_params;
proxy_pass http://localhost:1894;
}


  https://www.cnblogs.com/lailailai/p/4528092.html  

CORS - Cross Origin Resourse-Sharing - 跨站资源共享

CSRF - Cross-Site Request Forgery - 跨站请求伪造

 


 3.1 如何防止 CSRF 攻击

https://www.bilibili.com/video/av33502871/?spm_id_from=333.788.videocard.0

 CSRF 攻击:

当用户不小心在本机访问 fuck.com 黑客页面的时候,黑客页面上放了一个按钮或者一个表单(URL/action 为 http://you.com/delete-myself,当前用户登录过的网站),当用户触发这个按钮或表单的,浏览器发出 GET 或 POST 请求的时候,会带上 you.com 的 cookie;如果you.com网站没有做 CSRF 防御措施,那么这次请求在 you.com 看来会是完全合法的,但是实际上是黑客伪造的请求。

 

CSRF 防御:

CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求。(该请求中所有的用户验证信息都存在于Cookie中,攻击者可以在不知道这些验证信息的情况下直接利用用户自己的Cookie来通过安全验证。)

CSRF 主流防御方式是,用户每次发起请求之前,先从后端获取随机 token(后端同时将此 token 保存到缓存如redis中);

用户发起请求时携带该token,如果后端检查到没有 token或者提交的token和后端缓存的不一致,则请求失败;当token校验通过后,此toiken在缓存中被删除以防止token被冒用。

 

 *** 如何确保获取token的请求不是伪造的??

 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/793.html

相关文章

  • 前端跨域资源请求JSONP/CORS/反向代理

    摘要:此时完成的跨域代理配置仅仅是在开发环境下生效,到了生产环境下如果是放到服务器上则还需要借助的反向代理来进行跨域的代理。跨域 指的是浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的,是浏览器对 JavaScript 施加的安全限制。同源就是指 域名,协议,端口 均相同。两个网域若 域名、协议、端口 任一不同则二者的通信就出现了跨域问题,前端的跨域问题普通存在于两个阶段,一个是开发环境...

    番茄西红柿 评论0 收藏0
  • jsonp跨域获取数据实现百度搜索

    摘要:同源策略做了很严格的限制,但是在实际的场景中,又确实有很多地方需要突破同源策略的限制,也就是我们常说的跨域。使用跨域由于同源策略,一般来说位于的网页无法与不是的服务器沟通,而的元素是一个例外。 本菜鸡最近在写某个页面请求数据时,报了如下的错误。 Failed to load https://...:No Access-Control-Allow-Origin header is pre...

    Tikitoo 评论0 收藏0
  • jsonp跨域获取数据实现百度搜索

    摘要:同源策略做了很严格的限制,但是在实际的场景中,又确实有很多地方需要突破同源策略的限制,也就是我们常说的跨域。使用跨域由于同源策略,一般来说位于的网页无法与不是的服务器沟通,而的元素是一个例外。 本菜鸡最近在写某个页面请求数据时,报了如下的错误。 Failed to load https://...:No Access-Control-Allow-Origin header is pre...

    gggggggbong 评论0 收藏0
  • jsonp跨域获取数据实现百度搜索

    摘要:同源策略做了很严格的限制,但是在实际的场景中,又确实有很多地方需要突破同源策略的限制,也就是我们常说的跨域。使用跨域由于同源策略,一般来说位于的网页无法与不是的服务器沟通,而的元素是一个例外。 本菜鸡最近在写某个页面请求数据时,报了如下的错误。 Failed to load https://...:No Access-Control-Allow-Origin header is pre...

    lemanli 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<