第十五章——JavaScript客户端开发技术


运行期环境是由宿主环境通过脚本引擎创建的,实际上是由JavaScript引擎创建的一个代码解析初始化环境


  • 如果不是通过JavaScript脚本生成HTML网页的内容,一般放在HTML的head标签内;
  • 当需要使用JavaScript脚本生成HTML网页内容时,如某些JavaScript实现的动态树,就需要把js放在body之间。

使用伪URL地址引入JavaScript脚本代码:

onclick="JavaScript:alert('已经用鼠标点击文本框!')"

第十六章——JavaScript服务端开发技术

JavaScript本身是一门脚本语言,脚本语言常用来调用接口和功能。

服务端JavaScript的运行环境是node.js。简单的说,node.js就是运行在服务端的JavaScript, 是一个平台,是一个环境。该环境基于谷歌的V8引擎。

B/S技术:

- 用户只需安装一个浏览器Browser,服务器上安装数据库
- 用户界面完全通过WWW浏览器实现
- 一部分事务逻辑在前端实现
- 主要事务逻辑在服务端实现
- 浏览器通过web服务器同数据库进行交互

案例——制作网页版时钟

<!DOCTYPE html>
<html>

<head>
  <title>制作网页版时钟</title>
</head>

<body>
  <canvas id="canvas" width="200" height="200" style="border:1px solid #000;">您的浏览器不支持Canvas。</canvas>
  <script type="text/javascript" language="javascript" charset="utf-8">
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    if (ctx) {
      var timerId;
      var frameRate = 60;

      function canvObject() {
        this.x = 0;
        this.y = 0;
        this.rotation = 0;
        this.borderWidth = 2;
        this.borderColor = '#000000';
        this.fill = false;
        this.fillColor = '#ff0000';
        this.update = function () {
          if (!this.ctx) throw new Error('你没有指定ctx对象。');
          var ctx = this.ctx
          ctx.save();
          ctx.lineWidth = this.borderWidth;
          ctx.strokeStyle = this.borderColor;
          ctx.fillStyle = this.fillColor;
          ctx.translate(this.x, this.y);
          if (this.rotation) ctx.rotate(this.rotation * Math.PI / 180);
          if (this.draw) this.draw(ctx);
          if (this.fill) ctx.fill();
          ctx.stroke();
          ctx.restore();
        }
      };

      function Line() {};
      Line.prototype = new canvObject();
      Line.prototype.fill = false;
      Line.prototype.start = [0, 0];
      Line.prototype.end = [5, 5];
      Line.prototype.draw = function (ctx) {
        ctx.beginPath();
        ctx.moveTo.apply(ctx, this.start);
        ctx.lineTo.apply(ctx, this.end);
        ctx.closePath();
      };

      function Circle() {};
      Circle.prototype = new canvObject();
      Circle.prototype.draw = function (ctx) {
        ctx.beginPath();
        ctx.arc(0, 0, this.radius, 0, 2 * Math.PI, true);
        ctx.closePath();
      };

      var circle = new Circle();
      circle.ctx = ctx;
      circle.x = 100;
      circle.y = 100;
      circle.radius = 90;
      circle.fill = true;
      circle.borderWidth = 6;
      circle.fillColor = '#ffffff';

      var hour = new Line();
      hour.ctx = ctx;
      hour.x = 100;
      hour.y = 100;
      hour.borderColor = "#000000";
      hour.borderWidth = 10;
      hour.rotation = 0;
      hour.start = [0, 20];
      hour.end = [0, -50];

      var minute = new Line();
      minute.ctx = ctx;
      minute.x = 100;
      minute.y = 100;
      minute.borderColor = "#333333";
      minute.borderWidth = 7;
      minute.rotation = 0;
      minute.start = [0, 20];
      minute.end = [0, -70];

      var seconds = new Line();
      seconds.ctx = ctx;
      seconds.x = 100;
      seconds.y = 100;
      seconds.borderColor = "#ff0000";
      seconds.borderWidth = 4;
      seconds.rotation = 0;
      seconds.start = [0, 20];
      seconds.end = [0, -80];

      var center = new Circle();
      center.ctx = ctx;
      center.x = 100;
      center.y = 100;
      center.radius = 5;
      center.fill = true;
      center.borderColor = 'green';

      for (var i = 0, ls = [], cache; i < 12; i++) {
        cache = ls[i] = new Line();
        cache.ctx = ctx;
        cache.x = 100;
        cache.y = 100;
        cache.borderColor = "green";
        cache.borderWidth = 2;
        cache.rotation = i * 30;
        cache.start = [0, -70];
        cache.end = [0, -80];
      }

      timerId = setInterval(function () {
        // 清除画布
        ctx.clearRect(0, 0, 200, 200);
        // 填充背景色
        ctx.fillStyle = 'green';
        ctx.fillRect(0, 0, 200, 200);
        // 表盘
        circle.update();
        // 刻度
        for (var i = 0; cache = ls[i++];) cache.update();
        // 时针
        hour.rotation = (new Date()).getHours() * 30;
        hour.update();
        // 分针
        minute.rotation = (new Date()).getMinutes() * 6;
        minute.update();
        // 秒针
        seconds.rotation = (new Date()).getSeconds() * 6;
        seconds.update();
        // 中心圆
        center.update();
      }, (1000 / frameRate) | 0);
    } else {
      alert('您的浏览器不支持Canvas无法预览时钟!');
    }
  </script>

</body>

</html>

第十七章——JavaScript数据存储技术

Web Storage

1. sessionStorage

在本地存储一个会话session中大的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage并不是一个持久化的数据存储,仅仅是会话级别的数据存储。

2. localStorage

localStorage一存储在本地,数据存储是永久的,特点如下:

- 数据安全,永久保存,即客户端或浏览器中来自同一域名的所有页面都可访问localStorage
- 数据不会随着http请求发送到服务器
- 存储数据的大小,HTML5中要求至少支持4MB

方法:

- setItem(键名,键值)
- getItem(键值)
- removeItem(键值)
- clear(),移出本地存储所有数据

Indexed Database

简称indexedDB,是web客户端存储结构话数据的规范之一。

IndexedDB不支持SQL查询语句,更接近于NoSQL数据库。

- 键值对存储:采用对象仓存储 Object Store
- 异步性:不会锁死浏览器
- 支持事务:transaction,一步失败,事务回滚
- 同域限制:每一个域名对应一个数据库
- 存储空间大:不少于250MB
- 支持二进制存储
  1. var openRequest = indexedDB.open(“test”, 1)
    表示新建一个为test的数据库,版本号为1
  2. db = e.target.result;
  3. db.createObjectStore(“firstOS”):类似与表格的对象仓库

数据库事务:

- var t = db.transaction(["firstOS"], "readwrite") ;
- 可选参数: readonly, writeonly, readwrite

操作数据库数据:

- 添加数据:add(数据,键名)
- 读取数据:get(键名)
- 更新数据:put(数据, 键名)
- 删除数据:delete(键名)
- 遍历数据:openCursor()

第十八章——JavaScript错误和异常处理

window.onerror = function() { //处理逻辑 }

try-catch

第十九章——JavaScript的安全策略

安全策略

同源策略:
判断两个URL是否属于同一个源的方法:

- 协议相同
- 端口相同
- 域名相同

跨域请求:

  • 跨域资源共享(CORS)
var url = "https://wsuo.top";
document.cookie = "version=1";
$.ajax({ url : url })

运行这段代码之后,就会返回数据,同时不会被浏览器拦截,同时请求头多了一个字段:Access-Control-Allow-Origin,这个字段就是所谓的资源共享,它的值表示允许任意网站向这个接口请求数据。也可以这样:

response.writeHead(200, {"Access-Conteol-Allow-Origin":"http://wsuo.top"});
  • JSONP方法
    原理是客户端告诉服务器一个回调函数的名称,服务在返回的<script></script>里面调用这个回调函数,同时传进客户端需要的数据,这样返回的代码就在浏览器中执行了。

  • 子域跨父域
    子域跨父域是支持的,但是需要将子域的域名改成父域的,例如mail.mysite.com要请求mysite。com的数据,那么在mail.mysite.com脚本中要执行如下代码:

document.domain = "mysite.com";

常用的安全策略代码

  • 屏蔽部分按键
描述
8 退格键
13 回车键
116 F5
46 删除键
if(event.keyCode == 13) {
	event.keyCode = 0;
	event.returnValue = false;
	alert("当前设置不允许使用回车键");
}
  • 屏蔽鼠标右键
<script language=javascript>
  function click() {
     event.returnValue=false;
	 alert("当前设置不允许使用右键!");
  }
  document.oncontextmenu=click;
</script>
  • 禁止网页另存为,使用<noscript>
<noscript>
<iframe scr="*.htm"></iframe>
</noscript>
  • 禁止复制网页内容,使用oncopy事件
<body oncopy="alert('进制复制!');return false;"> 
  • JavaScript加密与解密

    • 加密:escape( );
    • 解密:unescape( );