八种方式实现跨域请求

浏览器的同源策略提到跨域不能不先说一下”同源策略”。 何为同源?只有当协议、端口、和域名都相同的页面,则两个页面具有相同的源。只要网站的 协议名protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用,会受到同源策略的限制。 同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用(通常指使用XMLHttpRequest请求)。 跨域请求方式 解决跨域问题,最简单的莫过于通过nginx反向代理进行实现,但是其需要在运维层面修改,且有可能请求的资源并不再我们控制范围内(第三方),所以该方式不能作为通用的解决方案,下面阐述了经常用到几种跨域方式: 方式一:图片ping或script标签跨域图片ping常用于跟踪用户点击页面或动态广告曝光次数。 script标签可以得到从其他来源数据,这也是JSONP依赖的根据。 缺点:只能发送Get请求 ,无法访问服务器的响应文本(单向请求) 方式二:JSONP跨域 JSONP(JSON with Padding)是数据格式JSON的一种“使用模式”,可以让网页从别的网域要数据。根据 XmlHttpRequest 对象受到同源策略的影响,而利用 <script>元素的这个开放策略,网页可以得到从其他来源动态产生的JSON数据,而这种使用模式就是所谓的 JSONP。用JSONP抓到的数据并不是JSON,而是任意的JavaScript,用 JavaScript解释器运行而不是用JSON解析器解析。所有,通过Chrome查看所有JSONP发送的Get请求都是js类型,而非XHR。 缺点: 只能使用Get请求不能注册success、error等事件监听函数,不能很容易的确定JSONP请求是否失败JSONP是从其他域中加载代码执行,容易受到跨站请求伪造的攻击,其安全性无法确保 方式三:CORS Cross-Origin Resource Sharing(CORS)跨域资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,确保安全的跨域数据传输。现代浏览器使用CORS在API容器如XMLHttpRequest来减少HTTP请求的风险来源。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。服务器一般需要增加如下响应头的一种或几种: Access-Control-Allow-Origin: *Access-Control-Allow-Methods: POST, GET, OPTIONSAccess-Control-Allow-Headers: X-PINGOTHER, Content-TypeAccess-Control-Max-Age: 86400跨域请求默认不会携带Cookie信息,如果需要携带,请配置下述参数: "Access-Control-Allow-Credentials": true// Ajax设置"withCredentials": true方式四:window.name+iframe window.name通过在iframe(一般动态创建i)中加载跨域HTML文件来起作用。然后,HTML文件将传递给请求者的字符串内容赋值给window.name。然后,请求者可以检索window.name值作为响应。 iframe标签的跨域能力;window.name属性值在文档刷新后依旧存在的能力(且最大允许2M左右)。每个iframe都有包裹它的window,而这个window是top window的子窗口。contentWindow属性返回<iframe>元素的Window对象。你可以使用这个Window对象来访问iframe的文档及其内部DOM。 <!-- 下述用端口 10000表示:domainA 10001表示:domainB--><!-- localhost:10000 --><script> var iframe = document.createElement('iframe'); iframe.style.display = 'none'; // 隐藏 var state = 0; // 防止页面无限刷新 iframe.onload = function() { if(state === 1) { console.log(JSON.parse(iframe.contentWindow.name)); // 清除创建的iframe iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); } else if(state === 0) { state = 1; // 加载完成,指向当前域,防止错误(proxy.html为空白页面) // Blocked a frame with origin "http://localhost:10000" from accessing a cross-origin frame. iframe.contentWindow.location = 'http://localhost:10000/proxy.html'; } }; iframe.src = 'http://localhost:10001'; document.body.appendChild(iframe);</script><!-- localhost:10001 --><!DOCTYPE html>...<script> window.name = JSON.stringify({a: 1, b: 2});</script></html>注意: ...

May 6, 2019 · 2 min · jiezi

rem适配移动设备

前言移动端 rem 适配方案回顾总结 如何使用 remrem 单位的计算参考 html 的根节点 font-size进行计算,根节点的字体变化,布局参考的 rem 页面也会相应进行缩放,次为 rem 布局的本质。 1. 动态改变 html 的 font-size 值几乎在每个浏览器中我们都将 html 的 font-size 初始化 为 16px , 我们动态改变的话可以暂时将 16px 设置为 rem 适配的根节点 font-size 初始值。 那么如何进行适配动态修改? 假设设计稿宽度 为 750px,我们定义了自己使用 1rem = 16px 的单位去布局,如何适配呢? 在 chrome 的 手机 iphone 模拟器宽度为 375px,正好为设计稿的 一半,我们可以口算: 当时的 1rem 应该等于初始化时 html 节点 font-size 的一半,即 newFontSize = 16/2 = 8px,这样一半对一半不就适配了吗... 从中得到公式 设计稿宽度/16px = 需要适配的设备宽度/8px,能够看出 新的 font-size 是参考 当前的设备宽度与原设计稿的宽度,进行等比缩放的 ...

April 24, 2019 · 2 min · jiezi

Service Worker 浅析

引言Progressive Web App, 简称 PWA,是提升 Web App 的体验的一种新方法,能给用户原生应用的体验。Service Worker 是 PWA 中的重要一部分。Service Worker 可以监听当前域下的功能性事件,比如拦截和处理网络请求、推送通知(push)、后台同步(sync),今天我们来了解一下 Service Worker什么是 Service WorkerService worker (简称 SW) 是一个注册在指定源和路径下的事件驱动 Worker。它采用 JavaScript 控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。你可以完全控制应用在特定情形(最常见的情形是网络不可用)下的表现。开始编写一个简单的 SW注册 Service Worker首先,我们通过 js 代码调用浏览器的 api,注册 SW,告诉浏览器 SW 文件的位置,Service Worker 支持 promise,所以写起来非常方便// main.jsif (navigator.serviceWorker) { window.addEventListener(‘DOMContentLoaded’, () => { navigator.serviceWorker .register(‘sw.js’) .then(function(swReg) { console.log(‘sucess ’, swReg); }) .catch(function(error) { console.error(‘fail !’, error); }) }) }sw 存在作用域的概念,上面注册的作用域为 ‘/’,如果注册的 js 文件地址为 ‘a/sw.js’,则 sw 的作用域为 ‘/a’开始缓存接下来的代码编写主要集中在 sw.js (sw 加载的 js 文件) 文件中,在 Service Worker 安装过程中,我们进行数据的缓存。缓存文件的重要角色是浏览器的 Cache API,将数据缓存下来。const cacheName = ‘myCache’const cacheArray = [ ‘/index.html’, ‘/index.css’, ‘/main.js’]self.addEventListener(‘install’, function(event) { // Perform install steps event.waitUntil( // 打开一个 Cache 对象 caches.open(CACHE_NAME) .then(function(cache) { // 缓存数组中的内容 return cache.addAll(urlsToCache); }) )})因为一个 Worker是使用一个构造函数创建的一个对象运行一个命名的JavaScript文件。这个文件包含将在工作线程中运行的代码,运行在另一个全局上下文中,不同于当前的window。在 sw.js 中,无法使用 window、操作 DOM 等,使用 self 关键字,来实引用 DedicatedWorkerGlobalScope。如果所有文件都成功缓存,则将安装 Service Worker。 如有任何文件无法下载,则安装步骤将失败。也意味着 Service Worker 启动失败event.waitUntil 确保浏览器关闭也仍然能够执行缓存和代理请求Service Worker 能够实现离线功能,主要是拥有代理请求的功能,我们能够在请求的时候有自己的操作空间,请求优先,请求失败从 Cache 读取缓存;请求成功,更新缓存。self.addEventListener(‘fetch’, (event) => { if (event.request.mode === ’navigate’) { return event.respondWith( fetch(event.request).catch(() => caches.match(OFFLINE_URL)) ) }})event.respondWith接收推送消息在 sw.js 的内部通过事件监听的方式执行对应的回调函数,接收外部的推送信息,只需要添加 push 事件监听即可self.addEventListener(‘push’, function(event) { const options = { body: ‘Yay it works.’, icon: ‘images/icon.png’, badge: ‘images/badge.png’ } self.registration.showNotification(title, options);})消息推送,配合 Web Server For Chrome 更方便开启后台同步功能在浏览器无网络请情况下,服务端推送消息,浏览器无法接收到,但是当网络连通时,浏览器就可以接收到服务端推送的信息。浏览器的请求也可以实现同样的功能,通过特殊的方式发送请求,网络连通时,请求才会发出去。// 请求navigator.serviceWorker.ready.then((registration) => { // 区分不同的事件 const tag = ’tag’; registration.sync.register(tag).then(() => { // do something… })})// 事件监听// sw.jsself.addEventListener(‘sync’, function (e) { console.log(e.tag === ’tag’) // true e.waitUntil(…)})工作周期图片来源,侵删初始化阶段: 页面加载、解析 Service Worker 的 js 文件安装阶段: 安装 Service Worker ,通常在安装中执行缓存工作阶段:监听各种事件,执行工作待机阶段:网页关闭,Service Worker 在浏览器处于"静默"的状态,有事件同送等重新开始,随后再次"静默"更新阶段:新的 sw 触发 install 事件,旧的 sw 出发 activate 事件Firebase 云信息传递 (FCM)Firebase 云信息传递 (FCM) 是一种跨平台消息传递解决方案,可供您免费、可靠地传递消息。可以发送通知消息以再次吸引用户并留住他们。在即时通讯等使用情形中,一条消息可将最多 4KB 的有效负载传送至客户端应用。浏览器的 Service Worker 的消息推送主要依赖 FCM,服务端消息推送传递到 FCM,然后再由 FCM 推送到客户端。传动门参考链接:Push CompanionGoole 官方文档掘金 - 使用Service Worker发送Push推送知乎 - PWA 入门: 理解和创建 Service Worker 脚本掘金 - 使用Service Worker进行后台同步 ...

March 30, 2019 · 2 min · jiezi

浏览器缓存详解

https://heyingye.github.io/20…转载于: https://heyingye.github.io/ 博客

March 15, 2019 · 1 min · jiezi

谷歌浏览器应用插件下载汇总

第一种方法(适用于从能科学上网到不能科学上网插件的搬迁)打开谷歌应用市场(该环境必须可以科学上网)找到自己想要下载的插件,如下:首先找到该应用的id(链接后面的一串英文就是id了),步骤如下:或者如果已经下载该插件的情况下,右击插件 -> 管理拓展程序 -> 也能找到id重点,打开http://chrome-extension-downl…,输入查找出来的id,点击下载即可…另一种方法:https://chrome.lanfanshu.cn/(不需要科学上网)https://www.crx4chrome.com/(不需要科学上网)

March 1, 2019 · 1 min · jiezi