004. 前端跨域资源请求: JSONP/CORS/反向代理
1.什么是跨域资源请求?
https://www.cnblogs.com/niuli1987/p/10252214.html
同源: 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。
1.1 同源策略 : 浏览器的一个安全功能,不同源的客户端js脚本在没有明确授权的情况下,不能读写对方资源。用于隔离潜在恶意文件的重要安全机制。
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。
使用js脚本读写非同源的资源会被拒绝的(跨域资源的引入是可以的,使用js读写则受限制),因此 XMLHttpRequest 受同源策略限制。
1.2 不受同源策略限制的(跨域资源的引入是允许的)
页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
如嵌入到页面中的<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
https://www.cnblogs.com/niuli1987/p/10252214.html
- 利用nginx 反向代理解决跨域问题 https://www.cnblogs.com/bninp/p/5694277.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接口,就可以跨源通信(包括客户端跨域读取cookie,跨域访问服务端资源)。
例如1: https://api.github.com/ 支持跨域资源请求
响应头中含有 Access-Control-Allow-Origin ; 它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

例2 :服务端配置响应头,客户端可跨域访问cookie
resp.setHeader("Access-Control-Allow-Origin", origin); // 允许指定域访问跨域资源
resp.setHeader("Access-Control-Allow-Credentials", "true"); // 允许客户端携带跨域cookie,此时origin值不能为“*”,只能为指定单一域名
2.2.1 springboot 后台服务 配置 支持 CORS
配置 WebMvcConfigurerAdapter, 可提支持 站外Ajax请求访问的跨域资源
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"
<!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.3 利用nginx 反向代理解决跨域问题
location /apis {
rewrite ^.+apis/?(.*)$ /$1 break;
include uwsgi_params;
proxy_pass http://www.baidu.com/;
}
对于浏览器来说,访问的就是同源服务器上的一个url。而nginx通过检测url前缀,把http请求转发到后面真实的物理服务器。并通过rewrite命令把前缀再去掉。这样真实的服务器就可以正确处理请求,并且并不知道这个请求是来自代理服务器的。
3. 跨域请求伪造 CSRF 防御
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的请求不是伪造的??
004. 前端跨域资源请求: JSONP/CORS/反向代理的更多相关文章
- JSONP、图片Ping、XMLHttpRequest2.0等跨域资源请求(CORS)
跨域:当协议.主域名.子域名.端口号中任意一个不相同时都不算同一个域,而在不同域之间请求数据即为跨域请求.解决方法有以下几种(如有错误欢迎指出)以请求图片url为例: 1.通过XMLHttpReque ...
- JavaScript跨域资源请求(CORS)解决方案
跨域:当协议.主域名.子域名.端口号中任意一个不相同时都不算同一个域,而在不同域之间请求数据即为跨域请求.解决方法有以下几种(如有错误欢迎指出)以请求图片url为例: 1.通过XMLHttpReque ...
- 跨域问题,解决方案-Nginx反向代理
跨域问题,解决之道 跨域问题,在日常开发过程中,是一个非常熟悉的名词.今天的话题,结合我之前的项目场景,讨论下<跨域问题,解决之道>. 跨域是什么 跨域问题,是由于JavaScript出于 ...
- [跨域]跨域解决方法之Ngnix反向代理
跨域原理:http://www.cnblogs.com/Alear/p/8758331.html 介绍Ngnix之前,我么先来介绍下代理是什么~ 代理相当于中间人,中介的概念 代理分为正向代理和反向代 ...
- 跨域资源请求(除jsonp以外)的方法
---------------------------------------------------------------------------------------------------- ...
- 前端跨域调请求 nginx反向代理
用 本地pc的目录,请求192.168.3.246的接口,以/api为标识 运行命令: 启动 nginx -s start 重启 nginx -s relaod 停止 nginx -s stop 查看 ...
- .net MVC下跨域Ajax请求(JSONP)
一.JSONP(JSON with Padding) 客户端: <script type="text/javascript"> function TestJsonp() ...
- JavaScript跨域调用、JSONP、CORS与ASP.NET Web API[共8篇]
[第1篇] 同源策略与JSONP 浏览器是访问Internet的工具,也是客户端应用的宿主,它为客户端应用提供一个寄宿和运行的环境.而这里所说的应用,基本是指在浏览器中执行的客户端JavaScript ...
- jsonp实现跨域资源访问
平时项目中处理ajax跨域资源请求时,例如www.example2.com上的某个页面要请求www.example1.com的数据,我们使用得较多的是jsonp方式.jsonp通过JavaScript ...
随机推荐
- shell脚本头,#!/bin/sh与#!/bin/bash的区别.
因为今天写了个小脚本,死活不成功,总是报文件或者目录不存在,问了一下我们马同学的正常写法,发现只有脚本头的区别,也就是今天本文要讲的#!/bin/sh与#!/bin/bash. 本文参考:https: ...
- Java(五、类和对象中的例题)
一.方法中的参数为数值型的(int) import java.util.Scanner; public class ScoreCalc { public void calc(int num1,int ...
- 关于input的一些问题解决方法分享
前言 input是我们接受来自用户的数据常用标签,在前端开发中,相信每个人都会用到这个标签,所以在开发过程中也时候也会遇到一些问题,本文的内容是我在跟input相爱相杀过程中产生的,在此记录分享一下. ...
- mysql的SQL_NO_CACHE(在查询时不使用缓存)和sql_cache用法
转自:http://www.169it.com/article/5994930453423417575.html 为了测试sql语句的效率,有时候要不用缓存来查询. 使用 SELECT SQL_NO_ ...
- JSP中的隐含对象
什么是JSP中隐含对象:容器自动创建,在JSP文件中可以直接使用的对象. 作用:JSP预先创建的这些对象可以简化对HTTP的请求,响应信息的访问. JSP中的隐含对象: 输入输出对象:request. ...
- java里常用的redis客户端简介
Redis的各种语言客户端列表,请参见Redis Client.其中Java客户端在github上start最高的是Jedis和Redisson.Jedis提供了完整Redis命令,而Redisson ...
- 影响 MySQL Server 性能的相关因素
MySQL 最多的使用场景是WEB 应用,那么我们就以一个WEB 应用系统为例,逐个分析其系统构成,进行经验总结,分析出数据库应用系统中各个环境对性能的影响. 商业需求对性能的影响 这里我们就拿一个看 ...
- PHP生成腾讯云COS请求签名
目标 使用 PHP 创建 COS 接口所需要的请求签名 步骤 按照官方示例(也许是我笨,我怎么读都觉得官方文档结构费劲,示例细节互相不挨着,容易引起歧义),请求签名应用在需要身份校验的场景,即非公有读 ...
- sql server 高可用故障转移(3)
虚拟磁盘创建 前面我们已经搭了域和两台sql 服务器, 下面我们准备让DC域服务器除了担当域控制器外,还行使另一个职能:充当集群共享存储. 集群共享存储是由群集内的每个节点都能共同访问的一个存储设备, ...
- 玩转Spring MVC(三)----spring基本配置文件
这篇文章总结一下spring mvc的基本配置,首先贴一张我的项目的目录截图,有一些多余的文件,大家不必在意: 用到的一些jar包在这:<a>http://download.csdn.ne ...