即使用了 https 也不要通过 query strings 传敏感数据

关于作者:xiaoheike

奥门永利误乐域 1

简介还没来得及写 :)
个人主页
·
我的文章
·
10
·
     

奥门永利误乐域 2

<a target=”_blank” name=”t18″ style=”color:rgb(12,137,207)”></a>history在h5中新增的属性和方法

h5中的history对象新增了两个新方法:history.pushState()和history.replaeState();
两种方法都允许我们添加和更新历史记录,它们的工作原理相同并且可以添加数量相同的参数。但是pushState()是在history栈中添加一个新的条目,replaceState()是替换当前的记录值。除了方法之外,还有popstate
事件
pushState(data,title[,url])和replaceState(data,title[,url])参数一样,参数说明如下:

  • data:一个表示状态的对象,json格式数据
  • title:一个string格式的标题(大多数浏览器不支持或忽略这个参数,最好用null代替)
  • url:一个url(用于替换当前URL)

当浏览会话记录的时候,不管点击前进或者后退按钮,还是使用history.go和history.back方法,popstate事件都会被触发。当事件发生时,浏览器会从history中取出URL和对应的state对象替换当前的URL和history.state。通过event.state也可以获取history.state
需要说明的是pushState只是将当前页面保存到history的历史记录中(并作为最近的一个记录),并且将当前浏览器的地址栏改为参数url指定的值,但并不会加载它。这点与普通的通过链接打开或浏览器地址输入url完全不一样。所以如果想在url改变的时候需要监听popstate事件。

利用history可以弥补ajax无法回退的缺陷。如下方法是模拟ajax操作的实现方法。

<input type="button" value="加1" onclick="add()" />
   <div id="info" style="border:red 1px solid;width:200px;padding:10px;">0</div>
<script>
    var info = document.getElementById('info');
    var i = 1;
    function add() {
        var data = {
            param : i,
            func : func
        };
        info.innerHTML = i;
        document.title = i;
        History.push(data);
        i++;
    }

    function func(i) {
        info.innerHTML = i;
        document.title = i;
    }

    History = function() {  
            var 
               list = [],
               index = 1,

               func, scope;

            function push(data) {
                if(typeof data !== 'object') return;

                if(typeof data.param == undefined || typeof data.func !== 'function') return;

                func = data.func;
                scope = data.scope;

                history.pushState({param: data.param}, index, '#' + index);
                index++;
            }

            window.onpopstate = function(e) {
                if(e.state) {
                    var state = e.state,
                        param = state.param;
                    if(param) {
                        func.call(scope, param);
                    }
                }
                else{
                    if(func){
                        func.call(scope, 0);
                    }

                }

            }

            return {
                push : push
            };
        }();
</script>

即使用了 https 也不要通过 query strings 传敏感数据

2017/10/16 · 基础技术 ·
HTTPS

本文由 伯乐在线
xiaoheike
翻译,艾凌风
校稿。未经许可,禁止转载!
英文出处:HttpWatch。欢迎加入翻译组

服务器端的 log 将明文记下完整 url;浏览器上的访问历史也会明文记下完整
url;Referrer headers 里也忠实记下完整 url,然后在别人家的 Google
Analytics 上显示。

我们经常听到的一个常见问题是:“URL
中的参数是否可以安全地传递到安全网站?”这个问题常常出现在客户看了
HttpWatch 捕获的 HTTPS 请求后,想知道还有谁可以看到这些数据。

 

例如,假设在一个查询中,使用如下安全的 URL 传递密码字符串:

https://www.httpwatch.com/?password=mypassword

HttpWatch 能够显示安全请求的内容,因为它与浏览器集成,因此它能够在
HTTPS 请求的 SSL
连接对数据加密之前查看数据。奥门永利误乐域 3

如果你使用网络嗅探器查看,例如
Network Monitor,对于同一个请求,你只能够查阅加密之后的数据。在数据包跟踪中没有可见的网址,标题或内容:

奥门永利误乐域 4

您可以信任 HTTPS 请求是安全的,只要:

  • 未忽略任何SSL证书警告
  • Web 服务器用于启动 SSL 连接的私钥在 Web 服务器本身之外不可用。

因此,在网络层面,URL 参数是安全的,但是还有一些其他基于 URL
泄漏数据的方法:

  1. URL 存储在 Web 服务器日志中–通常每个请求的完整 URL
    都被存放在服务器日志中。这意味着 URL
    中的任何敏感数据(例如密码)会以明文形式保存在服务器上。以下是使用查询字符串通过
    HTTPS奥门永利误乐域, 发送密码时存储在 httpwatch.com 服务器日志中的条目:
    **2009-02-20 10:18:27 W3SVC4326 WWW 208.101.31.210 GET
    /Default.htm password=mypassword 443 …
    通常认为即使是在服务器上,存储明文密码从来都不是好想法
    2.URLs are stored in the browser history – browsers save URL
    parameters in their history even if the secure pages themselves are
    not cached. Here’s the IE history displaying the URL parameter:
  2. URL 存储在浏览器历史记录中–即使安全网页本身未缓存,浏览器也会将
    URL 参数保存在其历史记录中。以下是 IE 的历史记录,显示了 URL
    的请求参数:奥门永利误乐域 5

如果用户创建书签,查询字符串参数也将被存储。

  1. URLReferrer 请求头中被传递–如果一个安全网页使用资源,例如
    javascript,图片或者分析服务,URL 将通过 Referrer
    请求头传递到每一个嵌入对象。有时,查询字符串参数可能被传递并存放在第三方站点。在
    HttpWatch 中,你可以看到我们的密码字符串正被发送到
    Google Analytics奥门永利误乐域 6

结论

解决这个问题需要两步:

  • 只有在绝对必要的情况下传递敏感数据。一旦用户被认证,最好使用具有有限生命周期的会话
    ID 来标识它们。

使用会话层级的 cookies 传递信息的优点是:

  • 它们不会存储在浏览器历史记录中或磁盘上
  • 它们通常不存储在服务器日志中
  • 它们不会传递到嵌入式资源,例如图片或 JavaScript
  • 它们仅适用于请求它们的域和路径

以下是我们的在线商店中,用于识别用户的 ASP.NET 会话 cookie 示例:

奥门永利误乐域 7

请注意,cookie 被限制在域
store.httpwatch.com,并且在浏览器会话结束时过期(即不会存储到磁盘)。

你当然可以通过 HTTPS
传递查询字符串,但是不要在可能出现安全问题的场景下使用。例如,你可以安全的使用它们显示部分数字或者类型,像
accountview 或者
printpage,但是不要使用它们传递密码,信用卡号码或者其他不应该公开的信息。

1 赞 收藏
评论

<a target=”_blank” name=”t12″ style=”color:rgb(12,137,207)”></a>读取拖放的文件

围绕读取文件信息,结合使用Html5拖放API和文件API,能够创造出令人瞩目的用户界面:在页面上创建了自定义的放置目标后,可以从桌面上把文件拖放到该目标。与拖放一张图片或者一个链接类似,从桌面上把文件拖放到浏览器中也会触发drop事件。而且可以在e.dataTransfer.files中读到被放置的文件,当然此时它是一个File对象,与童年过文件输入字段取得的File对象一样。

var droptarget = document.getElementById('droptarget');

function handleEvent(e){
    var info = '';
    var output = document.getElementById('output');
    var files, i, len;
    e.preventDefault();
    if(e.type == 'drop') {
        files = e.dataTransfer.files;
        i = 0;
        len = files.length;
        while(i < len){
            info += files[i].name + '(' + files[i].type + ',' + files[i].size + 'bytes<br>';
            i++;
        }
        output.innerHTML = info;
    }
}
droptarget.addHandler('dragenter',handleEvent,false);
droptarget.addHandler('drageover',handleEvent,false);
droptarget.addHandler('drop',handleEvent,false);

<a target=”_blank” name=”t9″ style=”color:rgb(12,137,207)”></a>FileReader类型

FlieReader类型实现的是一种异步文件读取机制。可以把FileReader想象成XMLHttpRequest,区别只是它读取的是文件心痛,而不是远程服务器。为了读取文件中的数据,FileReader提供了如下几个方法:

  • readAsText(file,
    encoding):以纯文本的形式读取文件,将读取到的文本保存在result属性中。
  • readAsDataURL(file):读取文件并将文件一数据URI的形式保存在result属性中
  • readAsBinaryString(file)(已废弃):读取文件并将一个字符串保存在result属性中,字符串中的每一个字符表示一字节
  • readAsArrayBuffer(file):读取文件并将一个包含文件内容的ArrayBuffer保存在result属性中。

由于读取过程是异步的,因此FileReader也提供了几个事件。其中最有用的三个事件是progress、error和load,分别表示是否又读取了新数据,是否发生了错误以及是否读完了整个文件。

var filesList = document.getElementById("files-list");
EventUtil.addHandler(filesList, "change", function(event){
    var info = "",
        output = document.getElementById("output"),
        progress = document.getElementById("progress"),
        files = EventUtil.getTarget(event).files,
        type = "default",
        reader = new FileReader();

    if (/image/.test(files[0].type)){
        reader.readAsDataURL(files[0]);
        type = "image";
    } else {
        reader.readAsText(files[0]);
        type = "text";
    }

    reader.onerror = function(){
        output.innerHTML = "Could not read file, error code is " + reader.error.code;
    };

    reader.onprogress = function(event){
        if (event.lengthComputable){
            progress.innerHTML = event.loaded + "/" + event.total;
        }
    };

    reader.onload = function(){

        var html = "";

        switch(type){
            case "image":
                html = "<img src=\"" + reader.result + "\">";
                break;
            case "text":
                html = reader.result;
                break;

        }
        output.innerHTML = html;
    };
});

<a target=”_blank” name=”t6″ style=”color:rgb(12,137,207)”></a>globalStorage对象

sessionStorage对象应该主要用于针对会话的小段数据的存储。如果需要跨越花花存储数据,那么globalStorage或者localStorage更为合适
要使用globalStorage,首先要制定哪些域可以访问该数据。可以通过方括号标记使用属性来实现。

//保存数据
globalStorage['wrox.com'].name = 'Nicholas';
//获取数据
var name = globalStorage['wrox.com].name;

在这里,访问的是针对域名wrox.com的存储空间。这个存储空间对于wrox.com及其所有子域都是可以访问的。
对globalStorage空间的访问,是依据发起请求的页面的域名、协议和端口来限制的(类似于ajax请求的同源策略)。如果实现不能确定域名,那么使用location.host作为属性名比较安全

globalStorage[location.host].name = 'Nicholas';
var book = globalStorage[location.host].getItem('book');

如果不使用removeItem()或者delete删除,或者用户为清除浏览器缓存,存储在globalStorage属性中的数据会一直保留在磁盘上。这让globalStorage非常适合在客户端存储文档或者长期保存用户偏好设置

<a target=”_blank” name=”t10″ style=”color:rgb(12,137,207)”></a>读取部分内容

File对象支持一个slice()方法以实现读取文件的一部分而不是全部内容,这个方法在FireFox中的实现叫mozSlice(),在chrome中的实现是webkitSlice(),Safiri的5.1及之前的版本不支持这个方法。Slice()方法接收两个参数:起始字节及要读取的字节数。这个方法返回一个Blob实例,Blob是File类型的父类型。下面是一个通用的函数,可以在不同实践中使用slice()方法:

function blobSlice(blob,startByte,length){
    if(blob.slice){
        return blob.slice(startByte,length);
    } else if(blob.webkitSlice){
        return blob.webkitSlice(startByte,length);
    } else if(blob.webkitSlice){
        return blob.webkitSlice(startByte,length);
    } else {
     return null;
    }
}

blob类型有一个size属性和一个type属性,而且它也支持slice()方法,以便进一步切割数据。通过FileReader也可以从Blob中读取数据。下面这个例子只读取文件的32B内容

var filesList = document.getElementById('files-list');
EventUtil.addHandler(filesList, "change", function(event){
         var info = "",
              output = document.getElementById("output"),
              progress = document.getElementById("progress"),
              files = EventUtil.getTarget(event).files,
              type = "default",
              reader = new FileReader();
              blob = blobSlice(files[0],0,32);

          if (blob){
              reader.readAsText(blob);
              reader.onerror = function(){
               outpit.innerHTML = 'could not read file,error code is' + reader.error.code;
           }
           reader.onload = function(){
            output.innerHTML = reader.result;
        };
     } else {
         alert('your browser does not support slice()');

          }

          reader.onerror = function(){
              output.innerHTML = "Could not read file, error code is " + reader.error.code;
          };

只读取文件的一部分可以节省时间,非常适合只关注数据中某个特定部分(如请求头部)的情况

<a target=”_blank” name=”t21″ style=”color:rgb(12,137,207)”></a>canvas

Canvas 通过 JavaScript 来绘制 2D 图形。
Canvas 是逐像素进行渲染的。
在 canvas
中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。

<a target=”_blank” name=”t22″ style=”color:rgb(12,137,207)”></a>Canvas 与 SVG 的比较

下表列出了 canvas 与 SVG 之间的一些不同之处。
Canvas

依赖分辨率
不支持事件处理器
弱的文本渲染能力
能够以 .png 或 .jpg 格式保存结果图像
最适合图像密集型的游戏,其中的许多对象会被频繁重绘

SVG

不依赖分辨率
支持事件处理器
最适合带有大型渲染区域的应用程序(比如谷歌地图)
复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
不适合游戏应用

<a target=”_blank” name=”t16″ style=”color:rgb(12,137,207)”></a>Worker全局作用域

关于Web
Worker,最重要的是要知道它所执行的JavaScript代码完全在另一个作用域,与当前网页中的代码不共享作用域。在Web
Worker中,同样有一个全局对象和其他对象以及方法。但是Web
Worker中的代码不能访问DOM,也无法通过任何方式影响页面的外观
Web
Worker中的全局对象是worker对象本身。也就是说,在这个特殊的全局作用域中,this和sele引用的都是worker对象。为便于处理数据,Web
Worker本身也是一个最小化的运行环境

  • 最小化的navgator对象 :
    online、appName、appVersion、userAgent、platform
  • 只读的location对象 : 所有属性都是只读的
  • self : 指向全局 worker 对象
  • 所有的ECMA对象,Object、Array、Date等
  • XMLHttpRequest构造器
  • setTimeout、setInterval、clearTimeout()和clearInterval()方法

在worker内部,调用close()方法也可以停止工作。Worker停止工作后就不会再有事件发生。
另外,Worker的全局作用域中提供了importScripts()方法。这个方法接收一个或多个指向JavaScript文件的URL。每个加载过程都是异步进行的,因此素有的脚本加载并执行完成之后,importScripts()才会执行

importScripts('file1.js','file2.js');

即使file2.js先于file1.js下载完,执行的时候仍然会按照先后顺序实行。而且,这些脚本是在Worker的全局作用域中执行,如果脚本中包含与页面香瓜你的JavaScript代码,那么脚本可能无法正确运行。

<a name=”t5″></a><a target=”_blank” name=”t8″ style=”color:rgb(12,137,207)”></a>File API

File
API在表单中的文件输入字段的基础上,又添加了一些直接访问文件信息的接口。H5在DOM中为文件输入元素添加了一个files集合,在通过文本输入字段选择了一或多个文件时,files集合中将包含一组File对象,每个File对象对应着一个文件。每个File对象都有下列只读属性

  • name: 本地文件系统的文件名
  • size: 文件的字节大小
  • type:字符串,文件的MIME类型。
  • lastModifiedDate:字符串,文件上一次被修改的事件(只有chrome实现了这个属性)

现在我们获取id为‘files-list’的input为file的元素,将该元素中上传的文件输出到控制台

var filesList = document.getElementById('files-list');
        EventUtil.addHandler(filesList,'change',funciton(e){
            var files = EventUtil.getTarget(e).files,
                i = 0,
                len = files.length;
            while(i<len){
                console.log(files[i].name + '('+files[i].type+','+files[i].size +'bytes)');
                i++;

            }
        })

<a name=”t2″></a><a target=”_blank” name=”t2″ style=”color:rgb(12,137,207)”></a>新增的API

语义:

能够让你更恰当地描述你的内容是什么。

连通性:

能够让你和服务器之间通过创新的新技术方法进行通信(web sockets等)。

离线 & 存储:

能够让网页在客户端本地存储数据以及更高效地离线运行(离线资源、在线和离线事件、DOM存储、IndexDB、自web应用程序中使用文件[FileReader])。

多媒体:

使 video 和 audio 成为了在所有 Web 中的一等公民。

2D/3D 绘图 & 效果:

提供了一个更加分化范围的呈现选择(canvas、webGL)。

性能 & 集成:

提供了非常显著的性能优化和更有效的计算机硬件使用(WebWorkers、XMLHttpRequest2、HistoryAPI、拖放、requestAnimationFrame、全屏API、指针锁定API、在线和离线事件)。

设备访问 Device Access:

能够处理各种输入和输出设备(触控事件touch、使用地理位置定位、检测设备方向)。

<a name=”t8″></a><a target=”_blank” name=”t19″ style=”color:rgb(12,137,207)”></a>2D绘图(canvas和svg)

<a name=”t6″></a><a target=”_blank” name=”t13″ style=”color:rgb(12,137,207)”></a>Web Workers

专用Web
Worker提供可一个简单的方法使的web内容能够在后台运行脚本。一旦worker创建后,它可以向由它的创建者指定的事件监听函数传递消息,这样改worker生成的所有任务就都会接收到这个消息。worker线程能够在不干扰UI的情况下执行任务。

发表评论

电子邮件地址不会被公开。 必填项已用*标注