跨域:指的是浏览器不能执行其余网站的脚本。它是由浏览器的同源策略形成的,是浏览器对 javascript 施加的安全限制。javascript
同源策略:是指协议,域名,端口都要相同,其中有一个不一样都会产生跨域。css
做者信息
github: https://github.com/Michael-lzg
掘金: https://juejin.im/post/5e0d4b...html
虽然如今大部分项目并不会使用它来解决跨域,可是只要是面试,涉及到跨域,基本都会问到这个知识点。他说利用 script 标签自然跨域的特性。前端
缺点:只能使用 get 请求,不推荐使用vue
原生实现java
<script> var script = document.createElement('script'); script.type = 'text/javascript'; // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数 script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback'; document.head.appendChild(script); // 回调执行函数 function handleCallback(res) { alert(JSON.stringify(res)); } </script> <!-- 服务端返回以下(返回时即执行全局函数): --> handleCallback({"status": true, "user": "admin"}) 复制代码
jquery ajax:node
$.ajax({ url: 'http://www.demo2.com:8080/login', type: 'get', dataType: 'jsonp', // 请求方式为jsonp jsonpCallback: 'onBack', // 自定义回调函数名 data: {} })
vue.js:jquery
this.$http .jsonp('http://www.demo2.com:8080/login', { params: {}, jsonp: 'onBack' }) .then(res => { console.log(res) })
使用 web 服务器的反向代理设置,这不是先后端跨域解决方案,而是属于运维层级的。webpack
一、nginx配置解决iconfont跨域 浏览器跨域访问js、css、img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入如下配置。nginx
location / { add_header Access-Control-Allow-Origin *; }
二、nginx反向代理接口跨域 跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不须要同源策略,也就不存在跨越问题。
实现思路:经过nginx配置一个代理服务器(域名与domain1相同,端口不一样)作跳板机,反向代理访问domain2接口,而且能够顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登陆。
#proxy服务器 server { listen 81; server_name www.domain1.com; location / { proxy_pass http://www.domain2.com:8080; #反向代理 proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名 index index.html index.htm; # 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用 add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为* add_header Access-Control-Allow-Credentials true; } }
当下项目中若是涉及到跨域,实际上都应该是后端经过设置 CORS 来解决的。CORS 是目前最主流的跨域解决方案,跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的 Web 应用被准许访问来自不一样源服务器上的指定的资源。
// 在node端设置一下请求头,容许接收全部源地址的请求 res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE') res.header('Access-Control-Allow-Headers', '*')
利用 node + webpack + webpack-dev-server 代理接口跨域。在开发环境下,因为 vue 渲染服务和接口代理服务都是 webpack-dev-server 同一个,因此页面与代理接口之间再也不跨域,无须设置 headers 跨域信息了。webpack.config.js 部分配置:
module.exports = { entry: {}, module: {}, ... devServer: { historyApiFallback: true, proxy: [{ context: '/login', target: 'http://www.demo2.com:8080', // 代理跨域目标接口 changeOrigin: true, secure: false, // 当代理某些https服务报错时用 cookieDomainRewrite: 'www.demo1.com' // 能够为false,表示不修改 }], noInfo: true } }
此方案仅限主域相同,子域不一样的跨域应用场景。
实现原理:两个页面都经过 js 强制设置 document.domain 为基础主域,就实现了同域。
父窗口:(www.domain.com/a.html)
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe> <script> document.domain = 'domain.com' var user = 'admin' </script>
子窗口:(child.domain.com/b.html)
<script> document.domain = 'domain.com' // 获取父窗口中变量 alert('get js data from parent ---> ' + window.parent.user) </script>
postMessage 是 HTML5 XMLHttpRequest Level 2 中的 API,且是为数很少能够跨域操做的 window 属性之一,它可用于解决如下方面的问题:
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe> <script> var iframe = document.getElementById('iframe') iframe.onload = function() { var data = { name: 'aym' } // 向domain2传送跨域数据 iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com') } // 接受domain2返回数据 window.addEventListener('message',function(e) { alert('data from domain2 ---> ' + e.data) },false) </script>
b.html:(www.domain2.com/b.html)
<script> // 接收domain1的数据 window.addEventListener('message',function(e) { alert('data from domain1 ---> ' + e.data) var data = JSON.parse(e.data) if (data) { data.number = 16 // 处理后再发回domain1 window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com') } },false) </script>
总结前端性能优化的方法
几种常见的JS递归算法
搭建一个vue-cli的移动端H5开发模板
封装一个toast和dialog组件并发布到npm
从零开始构建一个webpack项目
总结几个webpack打包优化的方法
一文读尽前端路由、后端路由、单页面应用、多页面应用
关于几个移动端软键盘的坑及其解决方案
浅谈JavaScript的防抖与节流