wordpress Ubuntu Tomcat 莱斯分布 xamarin lambda types upload tinymce Ractivejs 后台系统模板 河南普通话考试报名官网 pr序列设置哪个好 matlab对数函数 idea整理代码格式 div字体加粗 python开发教程 python多线程编程 python关键字 python中的for循环 python零基础 java接口类 java类的继承 java结构 java自定义异常 liunx命令大全 linuxtail命令 linux远程 javascript源代码 嵌入式linux驱动程序设计从入门到精通 redis入门指南 millenium c4d挤压 ipad上市时间 黑域怎么用 软媒u盘启动 快剪辑怎么录制视频 maya骨骼绑定 大话5g 黑客软件网
当前位置: 首页 > 学习教程  > 编程语言

谈谈跨域、同源策略、以及常见跨域解决方案

2020/9/19 15:40:27 文章标签:

谈谈跨域、同源策略、以及常见跨域解决方案

跨域:是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对js实施的安全限制。

同源策略

同源策略是一个安全策略。所谓的同源,指的是协议,域名、端口号相同。

限制了一下行为:

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM 和 JS 对象无法获取
  • Ajax请求发送不出去

解决方案 :

当然了,我梳理了几个我觉得工作中常用的,其他的自行去了解。

jsonp跨域

利用script标签没有跨域限制的漏洞,网页可以拿到从其他来源产生动态JSON数据,当然了JSONP请求一定要对方的服务器做支持才可以。

「与AJAX对比」
「JSONP优点」

兼容性比较好,可用于解决主流浏览器的跨域数据访问的问题。缺点就是仅支持get请求,具有局限性,不安全,可能会受到XSS攻击。

  1. 创建script标签

  2. 设置script标签的src属性,以问号传递参数,设置好回调函数callback名称

  3. 插入html文本中

  4. 调用回调函数,res参数就是获取的数据
    function jsonp({ url, params, cb }) { return new Promise((resolve, reject) => { window[cb] = function (data) { resolve(data); document.body.remove(script); } params = {…params,cb}; let arr = []; for(let key in params){ arr.push( k e y = {key}= key={params[key]}); } let script = document.createElement(‘script’); script.src = u r l ? {url}? url?{arr.join(’&’)}; document.body.appendChild(script); }) }

当然,jquery也支持jsonp的实现方式

 $.ajax({ url: 'http://www.baidu.cn/login', type: 'GET', dataType: 'jsonp', //请求方式为jsonp jsonpCallback: 'callback', data: { "username": "Nealyang" } }) 

「JSONP优点」

  1. 它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制
  2. 它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持
  3. 并且在请求完毕后可以通过调用callback的方式回传结果。

「JSONP缺点」

  1. 它只支持GET请求而不支持POST等其它类型的HTTP请求
  2. 它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题

跨域资源共享 CORS

CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。 上面是引用,你要记住的关键点

  • 浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。

  • 服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。

请求分为「简单请求」和「非简单请求」,所以我们的了解这两种情况。
「简单请求」

满足下面两个条件,就属于简单请求
条件1:使用下列方法之一:

  • GET
  • HEAD
  • POST

条件2:Content-Type 的值仅限于下列三者之一

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器; XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。

「复杂请求」

不符合以上条件的请求就肯定是复杂请求了。复杂请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求,该请求是 option 方法的,通过该请求来知道服务端是否允许跨域请求。
直接上一个例子吧 看看一个完整的复杂请求吧,并且介绍一下CORS请求的字段。

//server2.js
let express = require('express') 
let app = express()
let whitList = ['http://localhost:3000'] //设置白名单 
app.use(function(req, res, next) {
 let origin = req.headers.origin
 if (whitList.includes(origin)) { 
res.setHeader('Access-Control-Allow-Origin', origin) // 设置哪个源可以访问我res.setHeader('Access-Control-Allow-Headers', 'name')// 允许携带哪个头访问我 
 res.setHeader('Access-Control-Allow-Methods', 'PUT')  // 允许哪个方法访问我
res.setHeader('Access-Control-Allow-Credentials', true) // 允许携带cookie 
 res.setHeader('Access-Control-Max-Age', 6) // 预检的存活时间
 res.setHeader('Access-Control-Expose-Headers', 'name') // 允许返回的头
if (req.method === 'OPTIONS') { res.end() // OPTIONS请求不做任何处理 }
 }
 next() }) 
app.put('/getData', function(req, res) {
 console.log(req.headers) 
res.setHeader('name', 'jw') //返回一个响应头,后台需设置 res.end('我不爱你') 
}) app.get('/getData', function(req, res) {
 console.log(req.headers) res.end('我不爱你') 
})
 app.use(express.static(__dirname))
app.listen(4000) 

「与JSONP对比」

  • JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
  • 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
  • JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS)

本文链接: http://www.dtmao.cc/news_show_200287.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?