跨域会报40几_跨域与常用解决方法

什么是跨域

同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源。我们也可以把它称为“协议/主机/端口 tuple”,或简单地叫做“tuple". ("tuple" ,“元”,是指一些事物组合在一起形成一个整体,比如(1,2)叫二元,(1,2,3)叫三元)。(mdn)

上边这一段话来自于MDN,反正在我看来这么一大段干(gou)净(pi)利(bu)落(tong)的话实在是很官方,

说白了跨域就是说 主机名(域名)、协议、端口号只要有其一不同,就为不同的域,那么这个时候你去请求的话就会发生跨域

总之就是浏览器的一种叫做同源策略限制的东西在搞事情

同源策略限制

大概讲的是请求的时候会发送一个Origin报头到被请求的地址

然后被请求的地址返给请求者一个Access-Control-Allow-Origin响应头,如果值为*或者和Origin的站点对应,那么就可以请求,如果不对应就会跨域

同源策略限制这个东西我觉得主要就是针对请求,如果没有的话,假如你进入了一个需要登陆的网站,你登陆完成之后,浏览器保存了你的cookie,然后你在不退出的情况下中途访问了其他的恶意网站,这个恶意网站就可以盗取你的登陆信息去直接登陆你的账号

还有一种就是这个同源策略限制了dom的查询比如说我们项目中用到过iframe 这个标签 ,他可以将一个html页面嵌入到当前的页面中,如果说一个网站把另一个你信任的网站通过iframe嵌入到自己的网站的话,那么你输入的一切东西都会被人家看的一清二楚,有了同源策略的话一般都需要去代理其他域名或者加入白名单,才能引入那个域名的html,

可以说是同源策略限制给了用户一个基本的保护

url的组成(统一资源定位符)

一直以来,自从我接触前端以来,我就在不停的和url打交道,but我之前都是管这个东西叫域名的,

很是尴尬,

url中文叫做统一资源定位符,是互联网上一处资源的地址,一个完整的url主要有一下及部分组成

协议部分 ,比较常见的有http https ftp 等

域名部分,比如说www.baidu.com 这一块,也可以用服务器的ip作为域名使用

端口 ,可以不在浏览器中输入,不输入的时候浏览器默认的端口是80

目录部分 ,从域名后边以/开始以/结束,就好比我们电脑里边文件路径

文件名部分,从域名到路径,然后同理后边的是文件命名部分,比如说xxx.html,也可以不写这个文件命名,不写的时候会使用你的服务器设置的默认的文件命名

锚部分 从#开始,#代表页面中的一个位置,右边的字符就是这个位置的标识符,如果页面中有相对应的锚点的或者对应的id的话,浏览器会自动根据锚后边的字符串把可视视图定位到页面的锚点位置

(这个锚部分,用处非常多,到时候单独整理一盘博客)

参数部分 从? 开始,想必大家之前都见过有些网站的连接后边跟着一些参数,这些参数可以传给服务端,而且这一部分允许有多个参数,可以用&作为分隔符

跨域的几种常用解决方法

script标签,浏览器禁止了跨域的请求访问,但是可以引入其他域的script脚本,并能使用其中的方法,常用的浏览器可以通过load事件判断script是否加载完毕,ie是通过readystatechange属性

postMessage ,这是html5新加的一个新特性,跨文档消息传输Cross Document Messaging。

window.postMessage()方法可以安全的实现跨域通信,当方法被调用的时候,会在所有页面的脚本执行完毕之后,向目标窗口发送一个messageEvent的一个消息

otherWindow.postMessage(message, targetOrigin, [transfer]);

otherWindow

其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。

message

将要发送到其他 window的数据。

targetOrigin

通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"星号"(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。

transfer 可选

是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

在接收的window窗口下边可以增加一个监听

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event)

{

//回调

}

message对象有四个属性

data是第一个传的参数

origin 表示调用 postMessage 时消息发送方窗口的 origin . 包含了协议,域名和端口

source属性 发送消息的窗口对象的引用

JsonP跨域

上边说了script方法 其实这个可以说成是一种,另外补充下比如img link等 都具有跨域访问的能力

jsonp其实使用这个特性来实现跨域的,在jsonp里边可以定义回调函数,jsonp并不能替代请求,记得有一次微信公众号获取token跨域,jsonp并不能达到相应的效果,感觉jsonp 就是把script标签给封装了一下

CORS访问验证

W3C推荐了一种跨域的访问验证的机制,即CORS(Cross-Origin Resource Sharing 跨源资源共享)。 这种机制让Web应用服务器能支持跨站访问控制,使跨站数据传输更加安全,减轻跨域HTTP请求的风险。

CORS验证机制需要客户端和服务端协同处理

现在的各主流的浏览器都会对动态的跨域请求进行特殊的验证处理。验证处理分为简单请求验证处理和预先请求验证处理。

简单请求

当请求的方法是 GET HEAD POST 且请求头的Content-Type是

application/x-www-form-urlencoded

multipart/form-data

text/plain

之一的时候,浏览器会直接发送跨域请求,并在请求头中携带访问地址的header,

当服务端接收到请求之后,会根据自己的跨域规则,通过Access-Control-Allow-Origin和Access-Control-Allow-Methods响应头,来返回验证结果。

如果验证失败则不会返回资源

预先请求

与简单请求对应的 ,上述的六个条件,只要有一条不符合,浏览器在接收到请求的时候并不会立即执行请求的代码,而是会先发送一个option请求,用于访问服务器是否符合规范

正常来讲我们发送请求,比如post请求的时候,浏览器也会默认给我们加上一个options请求,他的主要用途就是获取服务器支持的http请求房和,和判断安全,

如果验证成功则会发送需要执行的请求,如果验证失败的时候则会返回一个403的状态

以上方法基本上就可以应对大部分的跨域的需求了,还有一些其他的方法比如说document.domain+iframe

如果是都在一个主源里边的话可以用一下,对于不同的源是无能为力的,沾个例子

//www.a.com上的a.html

document.domain = 'a.com';

var ifr = document.createElement('iframe');

ifr.src = 'http://script.a.com/b.html';

ifr.style.display = 'none';

document.body.appendChild(ifr);

ifr.onload = function(){

var doc = ifr.contentDocument || ifr.contentWindow.document;

// 在这里操纵b.html

alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);

};

//script.a.com上的b.html

document.domain = 'a.com';

比如上边这个www.a.com和script.a.com 他们的js是可以互通的,然后说明一下就是我们在日常用经常看到的www开头的域名 其实是二级域名

这里例子里边a.com才是主域名

以上是我对跨域和常用的解决方法的一些认知,有不足之处请多批评,我要去写bug了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
跨域是指在一个域名下的文档或脚本试图去请求另一个域名下的资源时,浏览器为了安全,阻止这种行为。跨域问题是由浏览器的同源策略(Same Origin Policy)引起的。同源策略是浏览器的一种安全机制,它限制了从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。 在Tomcat上解决跨域问题,可以通过配置CORS(Cross-Origin Resource Sharing)来实现。CORS是W3C规范,它允许在服务器端配置允许跨域访问的白名单。 下面是一个简单的Tomcat跨域配置示例: 1. 在Tomcat的conf目录下找到server.xml文件,在<Host>标签中添加以下配置: ```xml <Context path="/" docBase="your_doc_base" debug="0" reloadable="true"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127.0.0.1" /> <Filter className="org.apache.catalina.filters.CorsFilter"/> <FilterMapping filterName="CorsFilter" urlPattern="/*"/> </Context> ``` 2. 在Tomcat的lib目录下找到catalina.jar文件,将其解压。 3. 将解压后的catalina.jar中的META-INF目录下的context.xml文件拷贝到Tomcat的conf目录下,并修改其中的以下配置: ```xml <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127.0.0.1" /> <Filter className="org.apache.catalina.filters.CorsFilter"/> <FilterMapping filterName="CorsFilter" urlPattern="/*"/> ``` 4. 重启Tomcat。 以上就是一个简单的Tomcat跨域配置示例,如果您有其他问题或疑问,可以随时向我提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值