关于跨域及解决跨域

一、关于跨域

1、首先,我们需要知道的是:跨域是一种安全机制,而并不是问题

2、跨域概念

(1)跨域是浏览器加载了与当前域名、协议、端口不同的另一站点下的资源。
(2)跨域是与各大支持JS 的浏览器的同源策略是违背的
(3)同源策略:是由Netscape提出的一个著名的安全策略,是浏览器最核心也是最基础的安全功能,是为了保护本地数据不被javaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收,所谓的同源指的是:同域名,同端口,同协议
(4)举例了解同源:

  		以下这三个域名均为同源的:
  		    http://example.com/
			http://example.com:80/
			http://example.com/path/file
			
		以下这几个域名均不为同源:(有不同的协议,不同的端口,不同的域名)
			http://example.com/
			http://example.com:8080/
			http://www.example.com/
			https://example.com:80/
			https://example.com/
			http://example.org/
			http://ietf.org/

二、解决跨域

跨域并不会阻止请求的发出,也不会阻止请求的接收,跨域是浏览器为了保护当前的页面,你的请求得到了响应,浏览器不会把响应的数据交给页面上的回调,取而代之的区提示你这是一个跨域数据,会发生报错

1、CORS,跨域资源共享

这是最靠谱也是非常科学的解决方案,通过上面的截图我们可以看到,它提示了一个:从某某位置请求的资源被阻挡了,因为没有在响应头里发现:"Access-Control-Allow-Origin"的响应头。看到这个错误,我们不得不百度一下,这个Access-Control-Allow-Origin是个何方神圣。

通过Access-Control-Allow-Origin响应头,就告诉了浏览器。如果请求我的资源的页面是我这个响应头里记录了的"源",则不要拦截此响应,允许数据通行。比如说下面示列了一个场景:

	 		从 http://example.com 界面发出了一个请求到:		
			http://example2.com,因为不同源,导致了跨域。
			而 http://example2.com 返回了下面的响应头:
			Content-Type: application/json;charset=utf-8
			Content-Length: 3210
			Server: apache
			Access-Control-Allow-Origin: http://example.com

由于浏览器检测到 http://example2.com 的响应头中显示的写着:Access-Control-Allow-Origin: http://example.com,也就是,如果请求数据的源是 http://example.com 则可以允许访问返回的数据。这样浏览器就不会抛出错误提示,而是正确的将数据交给你的ajax回调。

在这个过程中跨域也存在,但跨域并没有导致问题了。因为后端的响应充分考虑到了某个页面源要使用这个资源,早就帮对方做好了跨域资源共享。这才可以顺利的进行对接。

所以,要最简单解决跨域导致的问题,只需要后端响应时,在响应头里指定允许调用资源的源就可以了。除了设定指定的源以外,你还可以直接写一个*号,这样就表示:此数据允许被任何其他的源进行获取。

现在,你了解了Access-Control-Allow-Origin,其实除了它,还有与之相关的更多字段,它们也起到了更多的个性定值效果。下面进行了详细介绍。在这里插入图片描述

2、使用JSONP方案

当服务端没有返回Access-Control-Allow-Origin这样的字段时,是否就意味着不能使用此资源了吗?不!只能说不建议使用此资源了。但我们还有另一种办法,那就是通过JSONP。看到这个名字,似乎和json有关,说有也有,但也可以说没有,JSONP只是大多数甚至全部人们对这种解决办法的称呼。

为了更灵活的使用这中解决办法,就必须要先了解它的实现原理。我们知道,在页面内使用ajax加载别的域名下的数据时,是会被跨域阻止的。那有没有办法让我们的请求不通过页内的ajax,而是让浏览器直接走这个请求?

有!如果你足够细心,你会发现,

是的,不过千万要注意,

我们先定义一个方法:

// 注意这是前端代码
var datasuccess = function (data) {
    // TODO
}

现在有了这个方法,我们将服务器返回的数据改成这种格式:

// 注意这是后端代码

response.getWrite().print(
	"datasuccess({
		name: \"Jack\", age: 23
	});"
);

后端通过返回一段js,而这段js实际上就是在执行之前定义好了的datasuccess方法,并且在执行的时候,还把一些数据传入了进来。嘶~~,这是什么啊,这不就正好我们可以在datasuccess方法里面拿到返回的data数据吗,而且还是在正确的时机进行执行。这样,数据就名正言顺的被我们拿到了啊!

它之所以叫JSONP,可能就是因为几乎所有后端在写返回数据的时候都是将数据参数传入的一个json对象。其实你可以甚至可以定义多个参数,每个参数的意义用途你也可以自己设定。

现在来看看一个完整的jsonp方法来进行跨域解决的代码:

// 先定义要执行的方法。
var datasuccess =function(data) {
    console.log("数据已获取:", data);
}
// 然后构建一个script节点,
var scriptDom = document.createElement("script");
scriptDom.src = "http://example2.com/?k=jack";
// 将节点添加到body,浏览器就会立即开始请求。当请求顺利,就会执行 datasuccess 方法
// 在该方法里执行获取到请求数据的逻辑。

而通常我们的接搜数据的方法名称并不是一直不变的,而是每次一个新的,在script节点中还会把方法名称传上去,让服务端知道我们获取数据的方法名,从而顺利的完成调用。

尽管这个方法很好,但是它只能走GET的请求方法,因为每次script节点的请求只有GET请求嘛。所以我们使用JSONP的接口,就只有GET方式。

了解下JSONP的原理

1、带填充的JSON,是一种可以在JS中绕过同源策略,并发起跨域HTTP请求的使用模式,可以启动JS的跨域HTTP请求
2、同源策略有一个显著的例外,HTML脚本元素是可以规避SOP(标准操作指导书)检查的。那就意味着我们可以采用动态注入脚本的方式向其他源发出HTTP请求。JSONP正是利用了这个例外情况进行跨域数据加载的。

3、VUE提供的代理配置

如果你是VUE项目,那么你在开发时,通常会配置一个代理,来完成跨域问题的修复,似乎没有后端的事情,但当你正式上线你才知道,代理没效果了。是的。现在介绍一下这个代理干了一件什么事情。

当你在开发VUE项目时,就必然会开一个server去实时预览你的代码效果,这是毋庸置疑的。但你要注意,开了一个server,这个server能做到事情,可不就是单单给你提供预览这么简单。它还可以进行请求转发,实际上你配置的那些代理,是先会请求到你的server,你开的server检查到你对应的配置,再请求你配的目标地址。这之间发生了什么,实际上就是把你的实际请求转到了你开的server里面去请求了,这就不存在什么浏览器同源安全的支配了,当然也就没有了跨域问题。

而当你上线项目时,如果你的代理配置得不够优雅,或者不够标准,你要小心了,非常有可能你的请求就都会失败。最佳的跨域解决方案,无非就是后端协助一起解决,单方面可不能达到完美。

4、react解决跨域

//在react脚手架中的package.json中加入一行代码:
"proxy":"http://localhost:8080"
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值