JavaScript 全栈教程(一)
一、基础
我认为每个人都应该学习如何给电脑编程,因为它教会你如何思考。我认为计算机科学是一门文科,是每个人都应该学会的。—史蒂夫·乔布斯
在本章中,我们将讨论以下主题:
- HTML、CSS 和 JavaScript 语法概述
- 敏捷方法简介
- 云计算、Node.js 和 MongoDB 的优势
- HTTP 请求/响应和 RESTful API 概念的描述
如果你是一个有经验的 web 开发人员,我不推荐,但是可以跳过这一章。在继续之前,温习一下基本概念是很重要的。为什么呢?也许你听说过并熟悉一些术语,但想知道它们实际上是什么意思。另一个很好的原因是,本章将以一种非常初学者友好的方式介绍 RESTful API。REST 在几乎所有现代 web 架构中都有使用,我们会在书中大量使用它。还有最后一个原因:在鸡尾酒会上,或者在你的同事和老板面前,你会显得很聪明。
前端定义
前端是浏览器应用的术语。在某些对话中,这可能意味着服务器首先面对请求。然而,对于这本书,我们假设所有的前端仅限于浏览器和移动应用及其代码。
前端开发,或前端 web 开发,意味着各种技术的使用。它们中的每一个单独来说都不太复杂,但是它们的数量之多让初学者感到胆怯。例如,有级联样式表(CSS)、超文本标记语言(HTML)、可扩展标记语言(XML)、JavaScript、JavaScript 对象标记法(JSON)、统一资源标识符(URI)、超文本传输协议(HTTP)和许多其他缩写。
除了底层技术,还有许多框架、工具和库;比如 jQuery,Backbone.js,Angular.js,Grunt 等等。请不要混淆前端框架和后端框架:后者运行在服务器上,而前者运行在浏览器上。
前端 web 开发由以下组件组成:
HTML or templates that compile to HTML Stylesheets to make HTML pretty JavaScript to add interactivity or some business logic to the browser app Some hosting (AWS, Apache, Heroku, etc.) Build scripts to prepare code, manage dependencies, and do pretty much anything that’s needed Logic to connect to the server (typically via XHR requests and RESTful API)
现在你知道前端开发人员这个头衔意味着什么了。掌握这个大杂烩的最大回报是通过构建漂亮有用的应用来表达你的创造力。
在我们开始构建之前,让我们鸟瞰一下 web 请求周期。
Web 请求周期
这对于刚接触 web 开发的人来说很重要。整个万维网或互联网是关于客户端和服务器之间的通信。这种通信通过发送请求和接收响应来实现。通常浏览器(最流行的 web 客户端)向服务器发送请求。在后台,服务器向其他服务器发送自己的请求。这些请求类似于浏览器请求。请求和响应的语言是 HTTP(S)。让我们更详细地研究浏览器请求。
web 请求由以下步骤组成:
A user types a URL or follows a link in his or her browser (also called the client). The browser makes an HTTP request to the server. The server processes the request, and if there are any parameters in a query string or body of the request, it takes them into account. The server updates, gets, and transforms data in the database. The server responds with an HTTP response containing data in HTML, JSON, or other formats. The browser receives the HTTP response. The browser renders an HTTP response to the user in HTML or any other format (e.g., JPEG, XML, JSON).
移动应用的行为方式与普通网站相同,只是没有浏览器,而是有一个本地应用。移动应用(原生或 HTML5)只是另一个客户端。手机和网络之间的其他微小差异包括运营商带宽导致的数据传输限制、更小的屏幕和更有效地使用本地存储。很可能你,我的读者,是一个渴望在移动中使用你的网页印章的网页开发者。有了 JavaScript 和 HTML5,这是可能的,因此有必要更深入地讨论 web 开发。
移动开发
手机会超越网络和桌面平台吗?也许吧。目前,移动开发领域还非常不成熟,还是一个新领域。如果你是先锋,那很好,但我们大多数人都不是。与 web 相比,这在工具和库方面是一个更大的差距。差距正在缩小。使用 HTML5,您可以编写一次代码并在移动设备上重用代码。还有其他方法。
这些是移动开发的方法,每种都有自己的优点和缺点:
Native: Native iOS, Android, Blackberry apps built with Objective-C and Java. Abstracted native: Native apps built with JavaScript in Appcelerator ( http://www.appcelerator.com ), Xamarin, ( https://xamarin.com ), Smartface ( http://www.smartface.io ) React Native or similar tools, and then compiled into native Objective-C or Java. Responsive: Mobile web sites tailored for smaller screens with responsive design, CSS frameworks like Twitter Bootstrap ( http://twitter.github.io/bootstrap/ ) or Foundation ( http://foundation.zurb.com/ ), regular CSS, or different templates. You might use some JavaScript frameworks for the development like Backbone.js, Angular.js, Ember.js, or React.js. Hybrid: HTML5 apps that consist of HTML, CSS, and JavaScript, and are usually built with frameworks like Sencha Touch ( http://www.sencha.com/products/touch ), Trigger.io ( https://trigger.io ), JO ( http://joapp.com ), React Native ( https://facebook.github.io/react-native ), or Ionic ( http://ionicframework.com ) and then wrapped into a native app with PhoneGap ( http://phonegap.com ). As in the third approach, you probably will want to use a JavaScript framework for the development, such as Backbone.js, Angular.js, Ember.js, or React.js.
我个人最喜欢的是第二和第四种方法。第二种方法不需要不同的代码库。只需向 CSS 库添加一个链接,就可以构建一个最小可行产品(MVP)。第四种方法更强大,提供了更具可伸缩性(从开发的角度来看)的 ui。这更适合复杂的应用。跨平台移动和 web 之间的代码重用很容易,因为大多数时候你是用 JavaScript 编写的。
超文本标记语言
HTML 本身不是一种编程语言。它是一组标记标签,描述内容并以结构化和格式化的方式呈现。HTML 标签由尖括号(<>)内的标签名称组成。在大多数情况下,标签包围着内容,结束标签在标签名称前有一个正斜杠。
在本例中,每一行都是一个 HTML 元素:
<h2>``Overview of HTML
<div>``HTML is a ...
<link``rel="stylesheet" type="text/css" href="style.css"
HTML 文档本身是<html>标签的一个元素,所有其他元素都是该<html>标签的子元素:
<!DOCTYPE html>
<html``lang="en"
<head>
<link``rel="stylesheet" type="text/css" href="style.css"
</head>
<body>
<h2>``Overview of HTML
<p>``HTML is a ...
</body>
</html>
HTML 有不同的风格和版本,比如 DHTML、XHTML 1.0、XHTML 1.1、XHTML 2、HTML 4 和 HTML 5。这篇文章很好地解释了不同之处:误解标记:XHTML 2/HTML 5 漫画( http://coding.smashingmagazine.com/2009/07/29/misunderstanding-markup-xhtml-2-comic-strip/ )。
任何 HTML 元素都可以有属性。其中最重要的是class, id, style, data-name, onclick,还有其他事件属性比如onmouseover, onkeyup等等。
class
属性定义了一个类,用于 CSS 或域对象模型(DOM)操作中的样式化;例如:
<p``class="normal"``>``...
id
属性定义了一个 ID,其目的类似于元素类,但是它必须是唯一的;例如:
<div id="footer">...</div>
style
属性定义内联 CSS 来样式化一个元素;例如:
<font style="font-size:20px">...</font>
title
属性指定了大多数浏览器通常在工具提示中显示的附加信息;例如:
<a title="Up-vote the answer">...</a>
data-name
属性允许元数据存储在 DOM 中;例如:
<tr data-token="fa10a70c-21ca-4e73-aaf5-d889c7263a0e">...</tr>
onclick
当点击事件发生时,onclick属性调用内联 JavaScript 代码;例如:
<input``type="button" onclick="validateForm();"``>``...
onmouseover
除了鼠标悬停事件,onmouseover属性类似于onclick;例如:
<a``onmouseover="javascript: this.setAttribute(’css’,’color:red’)"``>``...
内联 JavaScript 代码的其他 HTML 元素属性如下:
onfocus:当浏览器聚焦于一个元素时onblur:当浏览器焦点离开一个元素时onkeydown:当用户按下键盘按键时ondblclick:当用户双击鼠标时onmousedown:当用户按下鼠标按钮时onmouseup:当用户释放鼠标按钮时onmouseout:当用户将鼠标移出元素区时oncontextmenu:当用户打开上下文菜单时
事件兼容性表( http://www.quirksmode.org/dom/events/index.html )中提供了此类事件的完整列表和浏览器兼容性表。
我们将在 Twitter Bootstrap framework 中广泛使用类,但是使用内联 CSS 和 JavaScript 代码通常不是一个好主意,所以我们将尽量避免。然而,知道 JavaScript 事件的名称是有好处的,因为它们在 jQuery、Backbone.js 以及普通 JavaScript 中随处可见。要将属性列表转换成 JS 事件列表,只需去掉前缀on;例如,onclick属性表示click事件。
更多信息可在示例中找到:捕捉鼠标点击( https://developer.mozilla.org/en-US/docs/JavaScript/Getting_Started#Example:_Catching_a_mouse_click )、维基百科( http://en.wikipedia.org/wiki/HTML )和 MDN ( https://developer.mozilla.org/en-US/docs/Web/HTML )。
级联样式表
CSS 提供了一种格式化和显示内容的方法。一个 HTML 文档可以通过一个<link>标记包含一个外部样式表,如前面的例子所示,或者它可以在一个<style>标记中直接包含 CSS 代码:
<style>
body {
padding-top:``60px``;
}
</style>
每个 HTML 元素可以有id属性、class属性,或者两者都有:
<div``id="main" class="large"
Lorem ipsum dolor sit amet,
Duis sit amet neque eu.
</div>
在 CSS 中,我们通过元素的id、class、标签名来访问元素,在某些边缘情况下,通过父子关系或元素属性值来访问元素。
这会将所有段落的颜色(<p>标签)设置为灰色(#999999):
p {
color:``#999999
}
这会用main的id属性设置<div>元素的填充:
div#main {
padding-bottom:``2em
padding-top:``3em
}
这将类large的所有元素的字体大小设置为 14 像素:
.large {
font-size:``14pt
}
这隐藏了<div>,它是<body>元素的直接子元素:
body > div {
display:``none
}
对于name属性为email的输入,这将宽度设置为 150 像素:
input[name="email"] {
width:``150px
}
更多信息可查阅维基百科( http://en.wikipedia.org/wiki/Cascading_Style_Sheets )和 MDN ( https://developer.mozilla.org/en-US/docs/Web/CSS )。
CSS3 是对 CSS 的升级,包括一些新的处理方式,如圆角、边框和渐变,这些在常规 CSS 中只有借助 PNG/GIF 图像和使用其他技巧才能实现。
更多信息请参考 CSS3.info ( http://css3.info )、w3school ( http://www.w3schools.com/css3/default.asp ),以及 CSS3 与 CSS 关于扣球的对比文章( http://coding.smashingmagazine.com/2011/04/21/css3-vs-css-a-speed-benchmark )。
Java Script 语言
JavaScript (JS)于 1995 年在网景公司以 LiveScript 的名字出现。它与 Java 的关系就像仓鼠与火腿的关系一样,所以请不要混淆两者。
如今,JavaScript 被用于客户端和服务器端 web,以及桌面应用开发、无人机、物联网(IoT)和其他事物。这是本书的主要焦点,因为使用 JavaScript 你可以跨所有层进行开发。你不需要任何其他语言!
让我们从 HTML 中的 JavaScript 开始。将 JS 代码放入<script>标签是在 HTML 文档中使用 JavaScript 最简单的方法:
<script``type="text/javascript" language="javascript"
alert("Hello world!")
//simple alert dialog window
</script>
请注意,混合 HTML 和 JS 代码并不是一个好主意,所以为了将它们分开,我们可以将代码移动到一个外部文件,并通过在script标签上设置 source 属性src="filename.js"来包含它,例如,对于app.js资源:
<script``src="js/app.js" type="text/javascript" language="javascript"
</script>
请注意,结束标签</script>是强制的,即使是像我们包含外部源文件的空元素。由于 JavaScript 的压倒性优势,Type和language属性多年来在现代浏览器中成为可选属性。
运行 JavaScript 的其他方式包括:
- 内联方法已经介绍过了
- WebKit 浏览器开发工具和 FireBug 控制台
- 交互式
Node.js外壳
JavaScript 语言的优势之一是它是松散类型的。与 C 和 Java 等语言中的强类型( http://en.wikipedia.org/wiki/Strong_typing )相反,这种松散或弱类型使 JavaScript 成为更好的原型开发编程语言。下面是 JavaScript 对象或类的一些主要类型(本质上没有类;对象继承自对象)。
数字原语
数字原语是数值;例如:
var num = 1
数字对象
这是数( https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number )对象及其方法;例如:
var numObj = new Number(’123’) //Number object
var num = numObj.valueOf() //number primitive
var numStr = numObj.toString() //string representation
字符串原语
字符串原语是单引号或双引号内的字符序列;例如:
var str = ’some string’
var newStr = "abcde".substr(1,2)
为方便起见,JavaScript 自动用String对象方法包装字符串原语,但又不太一样( https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String#Distinction_between_string_primitives_and_String_objects )。
字符串对象
String对象有很多有用的方法,像length, match等等;例如:
var strObj = new String("abcde") //String object
var str = strObj.valueOf() //string primitive
strObj.match(/ab/)
str.match(/ab/) //both call will work
RegExp 对象
正则表达式是用于查找匹配、替换和测试字符串的字符模式。
var pattern = /[A-Z]+/
’ab’.match(pattern) // null
’AB’.match(pattern) // ["AB"]
match()方法返回一个匹配数组(["AB"])。如果你需要的只是一个布尔型的true/false,那么只需使用pattern.test(str)。例如:
var str = ’A’
var pattern = /[A-Z]+/
pattern.test(str) // true
特殊类型
有疑问的时候(调试的时候)随时可以调用typeof obj。以下是 JS 中使用的一些特殊类型:
NaN:不是数字null:空无一物,zipundefined:未声明的变量function:功能
数据
JSON 库允许我们解析和序列化 JavaScript 对象;例如:
var obj = JSON.parse(’{a: 1, b: "hi"}’)
var stringObj = JSON.stringify({a: 1, b: ’hi’})
数组对象
数组( https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array )是基于零索引的列表。例如,要创建数组:
var arr = new Array()
var arr = [’apple’, ’orange’, ’kiwi’]
Array对象有很多好的方法,比如indexOf、slice和join。确保你熟悉它们,因为如果使用正确,它们会节省很多时间。
数据对象
var obj = {name: ’Gala’, url: ’img/gala100x100.jpg’, price: 129}
或者
var obj = new Object()
稍后我们将提供更多关于继承模式的内容。
布尔原语和对象
就像String和Number,Boolean ( https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Boolean )可以是原语,也可以是对象。
var bool1 = true
var bool2 = false
var boolObj = new Boolean(false)
日期对象
Date ( https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date )对象允许我们处理日期和时间;例如:
var timestamp = Date.now() // 1368407802561
var d = new Date() // Sun May 12 2013 18:17:11 GMT-0700 (PDT)
数学对象
这些用于数学常数和函数()https://developer。mozilla。org/en-US/docs/JavaScript/Reference/Global _ Objects/Math);例如:
var x = Math.floor(3.4890)
var ran = Math.round(Math.random()*100)
浏览器对象
浏览器对象让我们能够访问浏览器及其属性,如 URLs 例如:
window.location.href = ’http://rapidprototypingwithjs.com
console.log(’test’)
DOM 对象
DOM 对象或 DOM(developer . Mozilla . org/en/docs/Web/API/Node)Node 是页面上呈现的 DOM 元素的浏览器接口。它们有宽度、高度、位置等属性,当然还有内部内容,可以是另一个元素或文本。要获得一个 DOM Node,可以使用它的 ID;例如:
var transactionsContainer = document.createElement(’div’)
transactionsContainer.setAttribute(’id’, ’main’)
var content = document.createTextNode(’Transactions’)
transactionsContainer.appendChild(content)
document.body.appendChild(transactionsContainer)
var main = document.getElementById(’main’)
console.log(main, main.offsetWidth, main.offsetHeight)
全球
除了像String、Array、Number和Math这样有很多有用方法的类之外,您还可以调用以下称为全局的方法,这意味着您可以从代码中的任何地方调用它们:
encodeURI(developer。mozilla。org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/encode uri):编码一个统一资源标识符(URI)给你一个 URL 比如encodeURI(’www.webapplog.com/js 很牛逼’)decodeURI(developer。mozilla。org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/decodeURI):解码一个 URIencodeURIComponent(developer。mozilla。org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/encodeURICompone nt):对 URL 参数进行 URI 编码(不要用于整个 URL 字符串)decodeURIComponent(developer。mozilla。org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/decodeURICompone nt):解码片段isNaN(developer。mozilla。org/en/docs/Web/JavaScript/Reference/Global _ Objects/isNaN):决定一个值是否为数字JSON(developer。mozilla。org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/JSON):JSON 数据的解析(parse())和序列化(stringify())parseFloat(developer。mozilla。org/en/docs/Web/JavaScript/Reference/Global _ Objects/parse float):将字符串转换为浮点数parseInt(developer。mozilla。org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/parse int):将字符串转换为数字Intl(developer。mozilla。org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/Intl):特定于语言的字符串比较方法Error(developer。mozilla。org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/Error):一个错误对象,可以用来实例化自己的错误对象;例如,throw new Error(’This book rocks!’)Date(developer。mozilla。org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/Date):处理日期的各种方法
约定
JavaScript 使用了许多样式约定。其中一个是 camelCase,你可以把多个单词打成一个单词,从第二个单词开始把每个单词的第一个字母大写。
分号是可选的。以下划线开头的名称是私有方法或属性,但不是因为它们受语言保护。我们使用_只是为了提醒开发人员不要使用它们,因为它们可能会在未来发生变化。
JavaScript 只支持最大 53 位的数字。如果你需要处理比大数更大的数,请查阅大数库。
JavaScript 和 DOM 对象的完整参考可从Mozilla Developer Network(https://developer . Mozilla . org/en-US/docs/JavaScript/Reference)和w3school(www . w3schools . com/jsref/default . ASP)获得。
对于 JS 资源,比如 ECMA 规范,请查看位于JavaScript Language Resources ( developer 的列表。mozilla。org/en-US/docs/JavaScript/Language _ Resources。在撰写本文时,最新的 JavaScript 规范是 ECMA-262 5.1 版。ECMA-国际。org/publications/files/ECMA-ST/Ecma-262。pdf )和 HTML(www . ECMA-international . org/ECMA-262/5 . 1/)。
JS 的另一个重要区别是它是一种函数式的原型语言。函数声明的典型语法如下所示:
function Sum(a,b) {
var sum = a + b
return sum
}
console.log(Sum(1, 2))
JavaScript 中的函数是一等公民(en . Wikipedia . org/wiki/First-class _ function)由于语言的函数编程(en . Wikipedia . org/wiki/Functional _ programming)性质。因此,函数可以用作其他变量或对象;例如,函数可以作为参数传递给其他函数:
var f = function (str1){
return function(str2){
return str1 + ’ ’ + str2
}
}
var a = f(’hello’)
var b = f(’goodbye’)
console.log((a(’Catty’))
console.log((b(’Doggy’))
知道有几种方法可以在 JS 中实例化一个对象是有好处的:
- 经典继承(www.crockford.com/javascript/…
- 伪经典继承(
javascript。信息/教程/伪经典模式模式 - 功能继承模式
要进一步了解继承模式,请查看 JavaScript 中的继承模式(bolin fest . com/JavaScript/Inheritance . PHP)和继承再访( developer)。mozilla。org/en-US/docs/JavaScript/Guide/Inheritance _ Revisited。
有关浏览器运行 JavaScript 的更多信息,请访问 Mozilla 开发者网络( developer。mozilla。org/en-US/docs/JavaScript/Reference)、维基百科(en . Wikipedia . org/wiki/JavaScript)、w3schools(www . w3schools . com/js/default . ASP)。
敏捷方法
敏捷软件开发方法的发展是由于传统方法如瀑布在高度不可预测的情况下不够好;也就是在解未知的时候( www。startuplessonsle 学到了。结合-敏捷-开发-与。html 。敏捷方法包括 Scrum/sprint、测试驱动开发、持续部署、成对编程和其他实用技术,其中许多都是从极限编程借鉴来的。
混乱
关于管理,敏捷方法使用 Scrum 方法。关于 Scrum 的更多信息可以从以下来源获得:
- PDF 格式的 Scrum 指南。scrumguides。org/docs/scrum guide/v1/scrum-guide-us。pdf
- Scrum.org()
- Scrum 开发维基百科文章(
en。维基百科。org/ wiki/ Scrum_(开发)
Scrum 方法是一系列短周期,每个周期被称为一次冲刺。一次冲刺通常持续一到两周。一个典型的 sprint 以一个 sprint 规划会议开始和结束,在这个会议上,新的任务被分配给团队成员。无法将新任务添加到正在进行的 sprint 中;它们只能在 sprint 会议上添加。
scrum 方法论的一个重要部分是每天的 Scrum 会议,因此得名。每次 scrum 是一个 5 到 15 分钟长的会议,通常在走廊上进行。在 scrum 会议中,每个团队成员都要回答三个问题:
What have you done since yesterday? What are you going to do today? Do you need anything from other team members?
灵活性使得敏捷成为瀑布方法的一个改进,特别是在高度不确定的情况下(例如,在创业中)。
Scrum 方法的优势在于,它在很难提前计划的情况下是有效的,在反馈循环被用作主要决策权威的情况下也是有效的。
测试驱动开发
测试驱动开发(TDD)由以下步骤组成:
Write failing automated test cases for new features, tasks, or enhancement by using assertions that are either true or false. Write code to successfully pass the test cases. Refactor code if needed, and add functionality while keeping the test cases passed. Repeat until all tasks are complete.
测试可以分为功能测试和单元测试。后者是指系统测试单个单元、方法和功能,并模拟出依赖关系,而前者(也称为集成测试)是指系统测试一部分功能,包括依赖关系。
TDD 有几个优点:
- 更少的错误和缺陷
- 更高效的代码库
- 确信代码能够工作,并且不会破坏旧的功能
持续部署和集成
持续部署(CD)是一套快速向客户交付新特性、缺陷修复和增强的技术。CD 包括自动化测试和自动化部署。使用 CD,减少了人工开销,并最大限度地缩短了反馈循环时间。基本上,开发人员越快从客户那里获得反馈,产品就能越快转向,从而在竞争中获得更多优势。许多初创公司在一天内部署多次,相比之下,大公司和大公司通常需要 6 到 12 个月的发布周期。
CD 方法的优点包括减少反馈循环时间和人工开销。
CD 和持续集成的区别在文章Continuous Delivery vs. Continuous Deployment vs. Continuous Integration - Wait huh? ( blog。安培拉。com/assembly blog/tabid/12618/bid/92411/连续交付-连续部署-连续集成-等等。aspx
一些最流行的持续集成解决方案包括:
- Jenkins(
Jenkins-ci . org/):一个可扩展的开源持续集成服务器 - circle ci(
circle ci . com/):发布更好的代码,更快 - Travis CI(
Travis-CI . org/):开源社区的托管持续集成服务
结对编程
结对编程是两个开发人员在一个环境中一起工作的一种技术。其中一个开发人员是司机,另一个是观察员。驱动编写代码,观察者通过观看和提出建议来辅助。然后他们交换角色。司机有一个更注重当前任务的战术角色。相比之下,观察者具有更具战略性的角色,监督“更大的画面”并发现错误和改进算法的方法。
以下是成对编程的优点:
- 结对产生更短更有效的代码库,并引入更少的错误和缺陷。
- 作为一个额外的奖励,知识在程序员们一起工作时传递。然而,开发人员之间的冲突是可能的,而且并不罕见。
后端定义
后端是服务器的另一个名称。是浏览器之后的一切。包括 PHP、Python、Java、Ruby,当然还有 Node.js 这样的服务器平台,以及数据库等技术。
幸运的是,借助现代后端即服务解决方案,您可以完全绕过后端开发。只需包含一个<script>标签,您就可以获得一个实时数据库,能够将一些逻辑放入其中,如访问级别控制(ALC)、验证等等。我说的是 Firebase.com 和 Parse.com。
在那些仍然需要自己的定制服务器代码的情况下,Node.js 是首选的武器!
Node.js
Node.js 是一种开源的、事件驱动的异步 I/O 技术,用于构建可伸缩的、高效的 web 服务器。Node.js 由 Google 的 V8 JavaScript 引擎( en。维基百科。org/wiki/V8 _(JavaScript _ engine))。它由云公司 Joyent 维护。com ),而是转移到技术指导委员会治理。
Node.js 的用途和用法类似于 Python 的 Twisted(Twisted matrix . com/TRAC/)和 Ruby 的 event machine(Ruby event machine . com/)。Node 的 JavaScript 实现是继尝试使用 Ruby 和 C++编程语言之后的第三个。
Node.js 本身并不是像 Ruby on Rails 那样的框架;它更像是 PHP 和 Apache 的组合。我将提供一个顶级 Node.js 框架的列表第六章。
以下是使用 Node.js 的优点:
- 开发人员很可能熟悉 JavaScript,因为它是 web 和移动开发的事实标准
- 使用一种语言进行前端和后端开发可以加快编码过程。开发人员的大脑不必在不同的语法之间切换,也就是所谓的上下文切换。方法和类的学习进行得更快。
- 有了 Node.js,你可以快速制作原型,并尽早进入市场进行客户开发和客户获取。这是相对于其他使用不太灵活的技术(例如 PHP 和 MySQL)的公司的一个重要的竞争优势。
- Node.js 通过利用 web 套接字来支持实时应用。
更多信息可以去维基百科(en . Wikipedia . org/wiki/Nodejs)、Nodejs.org(Nodejs . org/about/)和读写文章( readwrite)。com/2011/01/25/wait-whats-nodejs-good-for-aga)和 O ' Reilly(radar . oreilly . com/2011/07/what-is-node . html)。
关于 Node.js 目前的状态(截至本文撰写时),请参考 Node.js 官方博客(nodejs . org/en/blog/)。
NoSQL 和蒙古 b
来自 huMONGOus 的 MongoDB 是一个高性能、无关系的海量数据数据库。当传统的关系数据库管理系统(RDBMSs)无法应对海量数据的挑战时,NoSQL 概念应运而生。
以下是使用 MongoDB 的优势:
- 可伸缩性:由于分布式的特性,多个服务器和数据中心可以有冗余数据。
- 高性能:MongoDB 对于存储和检索数据非常有效,部分原因是数据库中的元素和集合之间没有关系。
- 灵活性:键值存储是原型开发的理想选择,因为它不需要开发人员了解模式,也不需要固定的数据模型或复杂的迁移。
云计算
云计算由以下组件组成:
- 基础设施即服务(IaaS),包括 Rackspace 和 Amazon Web Services
- 平台即服务(PaaS),包括 Heroku 和 Windows Azure
- 后端即服务(BaaS),最新、最酷的产品,包括 Parse.com 和 Firebase
- 软件即服务(SaaS),包括谷歌应用和 Salesforce.com
云应用平台具有以下优势:
- 可扩展性;例如,它们可以在几分钟内产生新的实例
- 易于部署;例如,要推送至 Heroku,您只需使用
$ git push - 按需付费计划,用户根据需求添加或删除内存和磁盘空间
- 用于简化数据库、应用服务器、软件包等的安装和配置的附加组件
- 安全和支持
PaaS 和 BaaS 是原型开发、构建最小可行产品(MVP)和早期创业公司的理想选择。
以下是最受欢迎的 PaaS 解决方案列表:
- 希罗库(http://希罗库)。com
- windows Azure(
windows Azure。com - nodejitsu(“??”)http://nodejitsu。com
- Nodester (
nodester。com
HTTP 请求和响应
每个 HTTP 请求和响应都由以下组件组成:
- Header:关于编码、正文长度、来源、内容类型等信息
- 主体:传递给服务器或发送回客户端的内容,通常是参数或数据
此外,HTTP 请求包含以下元素:
- 方法:有几种方法,最常见的有
GET、POST、PUT和DELETE - URL:主机、端口、路径。例如,
https://graph.facebook.com/498424660219540 - 查询字符串:URL 中问号后面的所有内容(例如,
?q=rpjs&page=20)
约定接口规范
RESTful(表述性状态转移)API 因分布式系统中的需求而变得流行,其中每个事务都需要包括关于客户端状态的足够信息。从某种意义上来说,这个标准是无状态的,因为服务器上没有存储关于客户机状态的信息,这使得不同的系统为每个请求提供服务成为可能。
以下是 RESTful API 的一些独特特征:
- 由于不同的组件可以独立部署到不同的服务器上,因此它具有更好的可扩展性支持。
- 因为更简单的动词和名词结构,它取代了简单对象访问协议(SOAP)。
- 它使用的 HTTP 方法有
GET、POST、DELETE、PUT、OPTIONS等等。
表 1-1 是一个用于消息收集的简单创建、读取、更新和删除(CRUD) RESTful API 的例子。
表 1-1。
An Example of a CRUD RESTful API
| 方法 | 统一资源定位器 | 意义 | | --- | --- | --- | | 得到 | /messages.json | 以 JSON 格式返回消息列表 | | 放 | /messages.json | 更新/替换所有消息并返回 JSON 中的状态/错误 | | 邮政 | /messages.json | 创建新消息并以 JSON 格式返回其 ID | | 得到 | /messages/{id}。数据 | 以 JSON 格式返回 ID 为{id}的消息 | | 放 | /messages/{id}。数据 | 更新/替换 ID 为{id}的消息,如果{id}消息不存在,请创建它 | | 删除 | /messages/{id}。数据 | 删除 id 为{id}的消息,以 JSON 格式返回状态/错误 |休息不是一个协议;它是一种比 SOAP 更灵活的架构,SOAP 是一种协议。因此,如果我们想要支持这些格式,REST API URLs 可能看起来像/messages/list.html或/messages/list.xml。
PUT和DELETE是幂等方法( en。维基百科。org/wiki/Hypertext _ Transfer _ Protocol # Idempotent _ methods _ and _ web _ applications),也就是说如果服务器收到两个或两个以上类似的请求,最终结果是一样的。GET是无效的,而POST不是幂等的,可能会影响状态并产生副作用。
关于 REST API 的进一步阅读可以在维基百科上找到。维基百科。org/wiki/presentation _ state _ transfer)以及 REST 文章简介(www . infoq . com/articles/REST-Introduction)。
摘要
第一章到此结束。在这一章中,我们已经讨论了一些网络开发的核心概念。它们将成为本书其余部分的坚实基础。我相信有些概念你很熟悉:
- 超文本标记语言
- 半铸钢ˌ钢性铸铁(Cast Semi-Steel)
- JavaScript 类型和对象
- 敏捷
- Node.js
- NoSQL
- HTTP 请求
- 约定接口规范
尽管如此,重温一下还是有好处的,因为它们数量众多,范围广阔。如果不理解理论如何应用并有益于实际代码,理论就没有那么有用或有趣。因此,我们将快速进入技术设置,让您快速进入编码项目。
二、设置
我最有效率的一天是扔掉了 1000 行代码。——肯·汤普森
在本章中,我们将讨论以下主题:
- 对工具集的建议
- 逐步安装本地组件
- 使用云服务的准备
正确的设置对生产发展至关重要。当你开始长途旅行时,你需要准备好一切,对吗?该工具集将使您富有成效,其他安装都是依赖项,如 Node.js 或 MongoDB。它们分别启用服务器端代码和持久性。除此之外,在云部分,我们将介绍部署和开发服务的设置。它们将使您能够将代码置于版本控制之下,并以可伸缩的方式进行部署。
本地设置
本地设置是我们在项目工作时在开发机器上使用的。它包括从文件夹、浏览器、编辑器、HTTP 服务器到数据库的任何东西。图 2-1 显示了初始开发环境设置的示例。
显影夹
如果您的 web 开发项目没有特定的开发文件夹,您可以在 Documents 文件夹中创建一个开发文件夹(路径将是Documents/Development)。为了处理代码示例,在 web 开发项目文件夹中创建一个fullstack-javascript文件夹;例如,如果您在Development文件夹中创建一个fullstack-javascript文件夹,路径将是Documents/Development/fullstack-javascript。您可以在 Mac OS X 上使用 Finder,或者在 OS X/Linux 系统上使用以下终端命令:
$ cd ∼/Documents
$ mkdir Development
$ cd Development
$ mkdir fullstack-javascript
图 2-1。
Initial development environment setup Tip
要从终端打开当前目录中的 Mac OS Finder 应用,只需键入并运行$ open .命令。在 Windows 上,终端是命令提示符。
要获取文件和文件夹列表,请使用以下 UNIX/Linux 命令:
$ ls
或者显示隐藏的文件和文件夹,如.git,使用这个:
$ ls -lah
$ ls的另一个替代物是$ ls -alt。-lah和-alt选项的区别在于,后者按时间顺序排序,而前者按字母顺序排序。
您可以使用 Tab 键自动完成文件和文件夹的名称。
稍后,您可以将示例复制到fullstack-javascript文件夹中,并在该文件夹中创建应用。
Tip
另一个有用的东西是在 Mac OS X 上的 Finder 中有新的“终端在文件夹中”选项。要启用它,请打开您的“系统偏好设置”(您可以使用 Command + Space,也就是 Spotlight)。找到键盘并点击它。打开键盘快捷键,然后点按“服务”。选中“在文件夹中新建端子”和“在文件夹中新建端子”复选框。关闭窗口(可选)。
浏览器
我们建议您选择下载最新版本的 WebKit ( http://en.wikipedia.org/wiki/WebKit )或 Gecko at [http://en.wikipedia.org/wiki/Gecko_(layout_engine](en.wikipedia.org/wiki/Gecko_… )浏览器:
- Chrome (
http://www.google.com/chrome)(推荐) - 游猎(
http://www.apple.com/safari/) - Firefox (
http://www.mozilla.org/en-US/firefox/new
鉴于 Chrome 和 Safari 已经内置了开发工具,你将需要 Firefox 的 Firebug 插件(图 2-2 )。
图 2-2。
Chrome Developer Tools in action
Firebug 和开发人员工具允许开发人员做许多事情,包括:
图 2-3。
Google tutorials for mastering web developer tools
- 调试 JavaScript
- 操纵 HTML 和 DOM 元素
- 动态修改 CSS
- 监控 HTTP 请求和响应
- 运行概要文件并检查堆转储
- 查看加载的资源,如图像、CSS 和 JS 文件
有一些很棒的 Chrome 开发者工具(DevTools)教程,比如下面的和图 2-3 和 2-4 中显示的:
图 2-4。
Mastering Chrome DevTools
- 用代码学校探索和掌握 Chrome DevTools (
http://discover-devtools.codeschool.com/) - Chrome DevTools 视频( [
https://developers.google.com/chrome-developer-tools/docs/videos](en.wikipedia.org/wiki/Gecko_… - Chrome DevTools 概述(
https://developers.google.com/chrome-developer-tools
ide 和文本编辑器
JavaScript 最大的好处之一就是你不需要编译代码。因为 JS 存在并运行在浏览器中,所以您可以在浏览器中进行调试!这是一种解释型语言,不是编译型语言。因此,我们强烈推荐一个轻量级的文本编辑器,而不是一个成熟的集成开发环境( http://en.wikipedia.org/wiki/Integrated_development_environment )或 IDE,但如果您已经熟悉并熟悉您选择的 IDE,如 Eclipse、(http://www.eclipse.org/)NetBeans(http://netbeans.org/)或 Aptana ( http://aptana.com/ ),请继续使用它。
以下是 web 开发中最流行的文本编辑器和 ide 列表:
图 2-6。
WebStorm IDE home page
图 2-5。
Sublime Text code editor home page
- TextMate (
http://macromates.com/):仅限 Mac OS X 版本,1.5 版免费 30 天试用,被称为 Mac OS X 的缺失编辑器 - 崇高文字(
http://www.sublimetext.com/): Mac OS X 和 Windows 版本都有。这是比 TextMate 更好的选择,具有无限的评估期(图 2-5 )。 - Coda (
http://panic.com/coda/):带 FTP 浏览器和预览的一体化编辑器,支持在 iPad 上开发。 - Aptana Studio (
http://aptana.com/):全尺寸 IDE,内置终端和许多其他工具。 - notepad++(http:notepad-plus-plus。org/ ):免费的仅支持 Windows 的轻量级文本编辑器,支持多种语言。
- WebStorm IDE (
http://www.jetbrains.com/webstorm/):功能丰富的 IDE,支持 Node.js 调试。它由 JetBrains 开发,并作为最智能的 JavaScript IDE 进行营销(图 2-6 )。 - MS Visual Studio (
https://www.visualstudio.com/features/node-js-vs):著名的 Visual Studio 环境的 Node.js 工具,来自 Redmond 的一家小公司。
版本控制系统
版本控制系统( http://en.wikipedia.org/wiki/Revision_control )即使在只有一个开发人员的情况下也是必不可少的。此外,许多云服务(例如 Heroku)需要 Git 进行部署。我们也强烈建议习惯 Git 和 Git 终端命令,而不是使用 Git 可视化客户端和带有 GUI 的应用:GitX ( http://gitx.frim.nl/ )、Gitbox ( http://www.gitboxapp.com/ )或 GitHub for Mac ( http://mac.github.com/。
Subversion 是一个非分布式版本控制系统。本文比较了 Git 和 Subversion(git.wiki.kernel.org/index.php/GitSvnComparison)。
以下是在您的机器上安装和设置 Git 的步骤:
Download the latest version for your OS at http://git-scm.com/downloads (Figure 2-7).
图 2-7。
Downloading latest release of Git Install Git from the downloaded *.dmg package; that is, run the *.pkg file and follow the wizard. Find the terminal app by using Command + Space, a.k.a. Spotlight (Figure 2-8), on OS X. For Windows you could use PuTTY ( http://www.chiark.greenend.org.uk/∼sgtatham/putty/ ) or Cygwin ( http://www.cygwin.com/ ).
图 2-8。
Using Spotlight to find and run an application In your terminal, type these commands, substituting "John Doe" and johndoe@example.com with your name and e-mail: $ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com To check the installation, run command: $ git version You should see something like this in your terminal window (your version might vary; in our case it’s 1.8.3.2, as shown in Figure 2-9): git version 1.8.3.2
图 2-9。
Configuring and testing Git installation
生成 SSH 密钥并将它们上传到 SaaS/PaaS 网站将在后面介绍。
本地 HTTP 服务器
虽然您可以在没有本地 HTTP 服务器的情况下进行大部分前端开发,但是在使用 HTTP 请求/AJAX 调用加载文件时需要使用本地 HTTP 服务器。此外,一般来说,使用本地 HTTP 服务器是一个很好的做法。这样,您的开发环境就尽可能接近生产环境。
我建议您使用基于 Node 的工具作为静态 web 服务器。它们缺少图形用户界面,但是简单快捷。你可以用 npm(自带 Node.js 说明在本章后面):
- node-static (
https://github.com/cloudhead/node-static):内置缓存的静态文件服务器。 - http-server (
https://www.npmjs.com/package/http-server):零配置命令行 http 服务器。
如果您更喜欢 GUI 而不是命令行界面(CLI ),您可能会考虑对 Apache web 服务器进行以下修改。MAMP,MAMP 堆栈和 XAMPP 有直观的图形用户界面,允许您更改配置和主机文件设置。
- MAMP (
http://www.mamp.info/en/index.html): Mac,Apache,MySQL,for Mac OS X 的个人 web 服务器 - MAMP 栈(
http://bitnami.com/stack/mamp):BitNami(苹果应用商店)构建的带有 PHP、Apache、MySQL、phpMyAdmin 栈的 Mac App(https://itunes.apple.com/es/app/mamp-stack/id571310406?l=en)。 - XAMPP (
http://www.apachefriends.org/en/xampp.html): Apache 发行版,包含适用于 Windows、Mac、Linux 和 Solaris 的 MySQL、PHP 和 Perl。
Mac 主页的 MAMP 如图 2-10 所示。
图 2-10。
MAMP for Mac home page
数据库:MongoDB
以下步骤更适合基于 Mac OS X/Linux 的系统,但稍加修改后,它们也可用于 Windows 系统(即$PATH变量,步骤 3)。这里我们描述官方包中的 MongoDB 安装,因为我们发现这种方法更健壮,导致的冲突更少。不过,也有很多其他方法可以在 Mac 上安装它( http://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/ ),例如使用 Brew,也可以在其他系统上安装( http://docs.mongodb.org/manual/installation/ )。
MongoDB can be downloaded at ( http://www.mongodb.org/downloads ). For the latest Apple laptops, like MacBook Air, select OS X 64-bit version. The owners of older Macs should browse the link at ( http://dl.mongodb.org/dl/osx/i386 ). Tip
要确定您的处理器的架构类型,请在命令行中键入$ uname -p。
Unpack the package into your web development folder (∼/Documents/Development or any other). If you want, you could install MongoDB into the /usr/local/mongodb folder. Optional: If you would like to access MongoDB commands from anywhere on your system, you need to add your mongodb path to the $PATH variable. For Mac OS X the open system paths file with: sudo vi /etc/paths or, if you prefer TextMate: mate /etc/paths And add this line to the /etc/paths file: /usr/local/mongodb/bin Create a data folder; by default, MongoDB uses /data/db. Please note that this might be different in new versions of MongoDB. To create it, type and execute the following commands in the terminal (Figure 2-11): $ sudo mkdir -p /data/db $ sudo chown id -u /data/db
图 2-11。
Initial setup for MongoDB: Create the data directory If you prefer to use a path other than /data/db you could specify it using the --dbpath option to mongod (the main MongoDB service). Go to the folder where you unpacked MongoDB. That location should have a bin folder in it. From there, type the following command in your terminal: $ ./bin/mongod If you see something like the following (and as in Figure 2-12) it means that the MongoDB database server is running: MongoDB starting: pid =7218 port=27017... By default, it’s listening at http://localhost:27017. If you go to your browser and type http://localhost:28017 you should be able to see the version number, logs, and other useful information. In this case the MondoDB server is using two different ports (27017 and 28017): One is primary (native) for the communications with apps and the other is a web-based GUI for monitoring and statistics. In our Node.js code we’ll be using only 27017. Don’t forget to restart the Terminal window after adding a new path to the $PATH variable.
图 2-12。
Starting up the MongoDB server Now, to take it even further, we can test to determine if we have access to the MongoDB console/shell, which will act as a client to this server. This means that we’ll have to keep the terminal window with the server open and running. Open another terminal window at the same folder and execute: $ ./bin/mongo You should be able to see something like "MongoDB shell version 2.0.6 ..." Then type and execute: > db.test.save( { a: 1 } ) > db.test.find() If you see that your record is being saved, then everything went well (Figure 2-13).
图 2-13。
Running MongoDB client and storing sample data Commands find and save do exactly what you might think they do.
详细说明也可登陆 MongoDB.org: Install MongoDB on OS X ( http://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x )。对于 Windows 用户,在Installing MongoDB ( http://www.tuanleaded.com/blog/2011/10/installing-mongodb )有一篇很好的介绍文章。
Note
MAMP 和 XAMPP 的应用附带了 MySQL——一个开源的传统 SQL 数据库——和 phpMyAdmin——一个 MySQL 数据库的 web 接口。
在 Mac OS X(和大多数 UNIX 系统)上,使用 Control + C 来关闭进程。如果使用 Control + Z,它将使进程进入睡眠状态(或分离终端窗口);在这种情况下,您可能会锁定数据文件,并且必须使用 kill 命令或活动监视器,并手动删除数据文件夹中的锁定文件。在普通的 Mac 终端命令+。是 Control + C 的替代。
其他组件
这些都是必需的技术。在进入下一章之前,请确保您有这些文件。
Node.js: We need it for build tools and back-end apps. Browser JS libraries: We need them for front-end apps. LESS app: We need it to compile LESS into CSS (Mac OS X only).
Node.js 安装
Node.js 在 http://nodejs.org/#download 可用(图 2-14 )。安装很简单:下载归档文件并运行*.pkg包安装程序。要检查 Node.js 的安装,您可以键入并执行:
$ node -v
我在这本书里用的是 v5.1.0,并且用 v5.1.0 测试了所有的例子。如果你用的是另一个版本,风险自负。我不能保证这些例子会运行。
假设您有 5.1.0 版本,它应该会显示如下内容:
v5.1.0
如果您想在 Node.js 的多个版本之间切换,有一些解决方案可以满足您的需求:
- nvm(
https://github.com/creationix/nvm”):node . js 版本管理器 - nave(
https://github.com/isaacs/nave):node . js 虚拟环境 - n(
https://github.com/tj/n”):node . js 版本管理
Node.js 包已经包含了 Node 包管理器( https://npmjs.org ) (NPM)。我们将广泛使用 NPM 来安装 Node.js 模块。
图 2-14。
Node.js home page
浏览器 JavaScript 库
前端 JavaScript 库从各自的网站下载和解包。这些文件通常放在开发文件夹中(例如:/Documents/Development)以备将来使用。通常,在缩小的生产版本(在第四章的 AMD 和 Require.js 部分有更多的介绍)和广泛丰富的注释开发版本之间有一个选择。
另一种方法是热链接来自 cdn 的这些脚本,例如 Google 托管库( https://developers.google.com/speed/libraries/devguide )、CDNJS ( http://cdnjs.com/ )、微软 Ajax 内容交付网络( http://www.asp.net/ajaxlibrary/cdn.ashx )等等。通过这样做,应用对一些用户来说会更快,但如果没有互联网,就根本无法在本地运行。
- 在
lesscss.org可以少做一个前端翻译。您可以将它解压到您的开发文件夹(∼/Documents/Development)或任何其他文件夹中。 - Twitter Bootstrap 是一个 CSS/LESS 框架。在
twitter.github.com/bootstrap有售。 - jQuery 在
jquery.com可用。 - Backbone.js 可在
backbonejs.org获得。 - 下划线. js 可在
underscorejs.org获得。 - Require.js 可在
requirejs.org获得。
更少的应用
LESS 应用是一个 Mac OS X 应用,用于将 LESS 动态编译为 CSS。在 incident57.com/less 有售(图 2-15 )。
图 2-15。
LESS App for Mac home page
云设置
下面几节讨论的云设置将允许您将代码置于版本控制之下,并以可伸缩的方式进行部署。
SSH 密钥
SSH 密钥提供了一个安全的连接,不需要每次都输入用户名和密码。对于 GitHub 库,后一种方法用于 HTTPS URL;比如https://github.com/azat-co/fullstack-javascript.git;前者使用 SSH URLs 比如git@github.com:azat-co/fullstack-javascript.git。
要在 Mac OS X/UNIX 机器上为 GitHub 生成 SSH 密钥,请执行以下操作:
Check for existing SSH keys: $ cd ∼/.ssh $ ls -lah If you see some files like id_rsa (please refer to Figure 2-16 for an example), you could delete them or back them up into a separate folder by using the following commands: $ mkdir key_backup $ cp id_rsa* key_backup $ rm id_rsa* Now we can generate a new SSH key pair using the ssh-keygen command, assuming we are in the ∼/.ssh folder: $ ssh-keygen -t rsa -C "your_email@youremail.com" Answer the questions; it is better to keep the default name of id_rsa. Then copy the content of the id_rsa.pub file to your clipboard (Figure 2-16): $ pbcopy < ∼/.ssh/id_rsa.pub
图 2-16。
Generating RSA key for SSH and copying public key to clipboard Alternatively, open id_rsa.pub file in the default editor: $ open id_rsa.pub Or in TextMate: $ mate id_rsa.pub
开源代码库
After you have copied the public key, go to github.com , log in, go to your account settings, select SSH Key, and add the new SSH key. Assign a name, such as the name of your computer, and paste the value of your public key. To check if you have an SSH connection to GitHub, type and execute the following command in your terminal: $ ssh -T git@github.com If you see something like this: Hi your-GitHub-username! You’ve successfully authenticated, but GitHub does not provide shell access. then everything is set up. The first time you connect to GitHub, you can receive an Authenticity of Host ... Can’t Be Established warning. Please don’t be confused with such a message—just proceed by answering Yes as shown in Figure 2-17.
图 2-17。
Testing SSH connection to GitHub for the very first time If for some reason you have a different message, please repeat Steps 3 and 4 from the previous section on SSH keys or reupload the content of your *.pub file to GitHub. Warning
保密你的文件,不要与任何人分享!
GitHub 提供了更多的说明:生成 SSH 密钥(help.github.com/articles/generating-ssh-keys)。
Windows 用户可能会发现[PuTTY]中的 SSH 密钥生成器功能非常有用。
微软云操作系统
以下是设置 Windows Azure 帐户的步骤:
You’ll need to sign up for Windows Azure Web Site and Virtual Machine previews. Currently they have a 90-day free trial available at https://azure.microsoft.com/en-us/ . Enable Git Deployment and create a user name and password, then upload the SSH public key to Windows Azure. Install the Node.js SDK, which is available at https://azure.microsoft.com/en-us/develop/nodejs/ . To check your installation type: $ azure -v You should be able to see something like this: Windows Azure: Microsoft’s Cloud Platform... Tool Version 0.6.0 Log in to Windows Azure Portal at https://windows.azure.com/ (Figure 2-18).
图 2-18。
Registering on Windows Azure Select New, then select Web Site, and Quick Create. Type the name that will serve as the URL for your web site, and click OK. Go to this newly created web site’s Dashboard and select Set Up Git Publishing. Come up with a user name and password. This combination can be used to deploy to any web site in your subscription, meaning that you do not need to set credentials for every web site you create. Click OK. On the follow-up screen, it should show you the Git URL to push to, something like this: https://azatazure@azat.scm.azurewebsites.net/azat.git You will also see instructions on how to proceed with deployment. We’ll cover them later. Advanced user option: Follow this tutorial to create a virtual machine and install MongoDB on it: Install MongoDB on a virtual machine running CentOS Linux in Windows Azure ( https://www.windowsazure.com/en-us/manage/linux/common-tasks/mongodb-on-a-linux-vm/ ).
赫罗库
Heroku 是一个多语言的敏捷应用部署平台(参见 http://www.heroku.com/ )。Heroku 的工作方式类似于 Windows Azure,你可以使用 Git 来部署应用。MongoDB 不需要安装虚拟机,因为 Heroku 有一个 MongoHQ 插件(addons.heroku.com/mongohq)。
要设置 Heroku,请按照下列步骤操作:
Sign up at ( http://heroku.com ). Currently they have a free account; to use it, select all options as minimum (0) and database as shared. Download Heroku Toolbelt at (toolbelt.heroku.com). Toolbelt is a package of tools; that is, libraries that consist of Heroku, Git, and Foreman ( github.com/ddollar/foreman ). For users of older Macs, get this client ( github.com/heroku/heroku ) directly. If you utilize another OS, browse Heroku Client GitHub ( github.com/heroku/heroku ). After the installation is done, you should have access to the heroku command. To check it and log in to Heroku, type: $ heroku login It will ask you for Heroku credentials (user name and password), and if you’ve already created the SSH key, it will automatically upload it to the Heroku web site (Figure 2-19).
图 2-19。
The response to the successful $ heroku login command If everything went well, to create a Heroku application inside of your specific project folder, you should be able to run this command: $ heroku create More detailed step-by-step instructions are available at Heroku: Quickstart ( devcenter.heroku.com/articles/quickstart ) and Heroku: Node.js ( devcenter.heroku.com/articles/nodejs ).
摘要
在这一章中,我们已经介绍了版本控制系统的技术设置、云客户端以及安装的各种工具和库。我们将在书中使用这些库和工具,因此安装并准备好它们是很重要的。此外,本章还提供了一些外部资源的链接,可以让你更好地理解和学习 web 开发工具。其中最有用的资源之一是 DevTools。
你一定很想开始真正的编码。等待结束了。在下一章中,我们将看到第一个 fullstack JavaScript 代码。
三、jQuery 和 Parse.com
构建一个软件设计有两种方式:一种是让它简单到没有明显的缺陷,另一种是让它复杂到没有明显的缺陷。第一种方法要困难得多。——东尼·霍尔
本章涵盖以下主题:
- JSON、AJAX 和 CORS 的定义
- 主要 jQuery 函数概述
- Twitter 引导脚手架
- 主要零部件较少
- OpenWeatherMap API 示例上 JSONP 调用的图示
- Parse.com 概述
- 关于如何使用 jQuery 和 Parse.com 构建留言板前端应用的说明
- 关于部署到 Windows Azure 和 Heroku 的分步说明
- 消息的更新和删除
本章是前端 web 开发的基本介绍。它涵盖了对 Twitter Bootstrap 等应用前端开发很重要的东西。这些令人惊叹的库让开发人员可以很快拥有一个漂亮的用户界面。
它涵盖了术语并解释了 JSON、AJAX 和 CORS。然后,我们探索天气应用的例子。
我们使用 Parse.com 作为我们的后端来简化事情,使开发更快,同时仍然保持现实。本章的基础是用 Parse.com 和 jQuery 构建的持久性留言板应用。
定义
在此之前,让我们先澄清一些术语。它们非常重要,足以让我们停下来熟悉它们。如果这些对你来说很熟悉,你可能想跳过。
JavaScript 对象符号
下面是来自 www 的 JavaScript 对象表示法(JSON)的定义。json。组织
JavaScript Object Notation(JSON)是一种轻量级的数据交换格式。对人类来说,读和写很容易。机器很容易解析生成。它基于 JavaScript 编程语言的子集,标准 ECMA-262 第三版-1999 年 12 月 ( www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf )。
JSON 是一种完全独立于语言的文本格式,但是它使用了 C 语言系列的程序员所熟悉的约定,包括 C、C++、C#、Java、JavaScript、Perl、Python 和许多其他语言。这些特性使 JSON 成为理想的数据交换语言。
JSON 已经成为在 web 和移动应用以及第三方服务的不同组件之间传输数据的标准。JSON 也广泛用于应用内部,作为配置、地区、翻译文件或任何其他数据的格式。
典型的 JSON 对象如下所示:
{
"a": "value of a",
"b": "value of b"
}
我们有一个带有键/值对的对象。键在冒号(:)的左边,值在冒号的右边。在计算机科学术语中,JSON 相当于哈希表、键列表或关联数组(取决于特定的语言)。JSON 和 JS object literal notation(原生 JS 对象)之间唯一的大区别是,前者更严格,要求键标识符和字符串值使用双引号(")。假设我们有一个字符串格式的有效 JSON 对象,这两种类型都可以用JSON.stringify()序列化为字符串表示,用JSON.parse()反序列化。
然而,对象的每个成员都可以是数组、原语或另一个对象;例如:
{
"posts": [{
"title": "Get your mind in shape!",
"votes": 9,
"comments": ["nice!", "good link"]
}, {
"title": "Yet another post",
"votes": 0,
"comments": []
}
],
"totalPost": 2,
"getData":``function ()
return new Data().getDate();
}
}
在这个例子中,我们有一个带有posts属性的对象。属性的值是一个对象数组,每个对象都有title、votes和comments键。属性保存一个数字原语,而属性是一个字符串数组。我们也可以用函数作为值。在这种情况下,键被称为方法;也就是getData。
JSON 比 XML 或其他数据格式灵活和紧凑得多,如本文所述:JSON:XML 的无脂肪替代品 ( www.json.org/xml.html )。为了方便起见,MongoDB 使用了一种类似 JSON 的格式,称为二进制 JSON ( bsonspec。org ) (BSON),稍后在 BSON 的第七章中进一步讨论。
创建交互式、快速动态网页应用的网页开发技术
在客户端(浏览器)使用异步 JavaScript 和 XML (AJAX)通过利用 JavaScript 语言中的XMLHttpRequest对象来发送和接收来自服务器的数据。尽管有这个名字,但并不要求使用 XML,通常使用 JSON。这就是为什么开发者几乎再也不说 AJAX 了。请记住,HTTP 请求可以同步发出,但是这样做并不是一个好的做法。同步请求最典型的例子是包含<script>标签。
跨域呼叫
出于安全原因,当客户端代码和服务器端代码位于不同的域时,XMLHTTPRequest 对象的初始实现不允许跨域调用。有一些方法可以解决这个问题。
其中之一就是使用 JSONP(en . Wikipedia . org/wiki/JSONP),带 padding/前缀的 JSON。这基本上是通过 DOM 生成的<script>标签进行的动态操作。脚本标签不属于相同的域限制。JSONP 请求在请求查询字符串中包含回调函数的名称。例如,jQuery.ajax()函数自动生成一个惟一的函数名,并将其附加到请求中(为了便于阅读,将一个字符串分成多行):
https://graph.facebook.com/search
?type=post
&limit=20
&q=Gatsby
&callback=jQuery16207184716751798987_1368412972614&_=1368412984735
第二种方法是使用跨源资源共享(CORS(www . w3 . org/TR/CORS)),这是一个更好的解决方案,但是它需要控制服务器端来修改响应头。我们在留言板示例应用的最终版本中使用这种技术。以下是 CORS 服务器响应标头的示例:
Access-Control-Allow-Origin: *
更多关于 CORS 的信息可以在资源中通过启用 CORS ( http://enable-cors.org/resources.html )和使用 CORS 通过 HTML5 岩石教程( http://www.html5rocks.com/en/tutorials/cors/ )获得。你可以在 test-cors.org 测试 CORS 的请求。
jQuery 函数
在培训期间,我们将使用 jQuery ( http://jquery.com/ )进行 DOM 操作、HTTP 请求和 JSONP 调用。jQuery 成为事实上的标准是因为它的$对象或函数,它提供了一种简单而有效的方法,通过 ID、类、标记名、属性值、结构或它们的任意组合来访问页面上的任何 HTML DOM 元素。语法非常类似于 CSS,我们用#表示 id,用.表示类选择。例如:
$(’#main’).hide()
$(’p.large’).attr(’style’,’color:red’)
$(’#main’).show().html(’<div>new div</div>’)
下面是最常用的 jQuery API 函数列表:
find() (http://api.jquery.com/find):根据提供的选择器字符串选择元素hide() (http://api.jquery.com/hide):隐藏可见的元素show() (http://api.jquery.com/show):显示一个隐藏的元素html() (http://api.jquery.com/html):获取或设置一个元素的内部 HTMLappend() (http://api.jquery.com/append)将一个元素注入到选中元素后的 DOM 中prepend() (http://api.jquery.com/prepend)将一个元素注入到选定元素之前的 DOM 中on() (http://api.jquery.com/on):将事件监听器附加到元素off() (http://api.jquery.com/off)从元素中分离事件监听器css() (http://api.jquery.com/css):获取或设置元素的样式属性值attr() (http://api.jquery.com/attr)获取或设置元素的任意属性val() (http://api.jquery.com/val):获取或设置元素的值属性text() (http://api.jquery.com/text):获取元素及其子元素的组合文本each() (http://api.jquery.com/each):迭代一组匹配的元素
大多数 jQuery 函数不仅作用于调用它们的单个元素,如果选择的结果有多个项目,还作用于一组匹配的元素。这是一个导致错误的常见陷阱,通常发生在 jQuery 选择器太宽的时候。
此外,jQuery 有许多可用的插件和库,它们提供了丰富的用户界面或其他功能。例如:
- jQuery UI (
http://jqueryui.com/ - jQuery Mobile (
http://jquerymobile.com/
Twitter 引导
引导您完成实施并演示项目的补充视频: http://bit.ly/1RKx9uY 。
Twitter Bootstrap(get Bootstrap。com )是 CSS/LESS 规则和 JavaScript 插件的集合,用于创建良好的用户界面和用户体验,而无需在圆角按钮、交叉兼容性、响应性等细节上花费大量时间。这个集合或框架非常适合你的想法的快速原型制作。然而,由于其可定制的能力,Twitter Bootstrap 也是严肃项目的良好基础。源代码是用 LESS(lessscss 写的。org ),但是普通的 CSS 也可以下载使用。
这里有一个简单的例子,使用 Twitter Bootstrap 搭建版本 4.0.0-alpha。项目的结构应该是这样的:
/01-bootstrap
-index.html
/css
-bootstrap.css
-bootstrap.min.css
... (other files if needed)
/js
-bootstrap.js
-bootstrap.min.js
-npm.js
首先让我们用适当的标签创建index.html文件:
<!DOCTYPE html>
<html``lang="en"
<head>
</head>
<body>
</body>
</html>
包含 Twitter 引导库作为一个缩小的 CSS 文件:
<!DOCTYPE html>
<html``lang="en"
<head>
<link
type="text/css"
rel="stylesheet"
href="css/bootstrap.min.css" />
</head>
<body>
</body>
</html>
应用具有container-fluid和row-fluid等级的脚手架:
<body >
<div``class="container-fluid"
<div``class="row-fluid"
</div>``<!--``row-fluid
</div>``<!--``container-fluid
</body>
Twitter Bootstrap 使用 12 列网格。单个小区的大小可以由类别spanN指定,例如span1、span2、span12。还有offsetN类,比如offset1,offset2,...offset12,向右移动单元格。完整的参考资料可在 http://twitter.github.com/bootstrap/scaffolding.html 获得。
我们将对主要内容块使用span12和hero-unit类:
<div``class="row-fluid"
<div``class="span12"
<div``id="content"
<div``class="row-fluid"
<div``class="span12"
<div``class="hero-unit"
<h1>
Welcome to Super
Simple Backbone
Starter Kit
</h1>
<p>
This is your home page.
To edit it just modify
the``<i>``index.html``</i>
</p>
<p>
<a
class="btn btn-primary btn-large"
href="http://twitter.github.com/bootstrap
target="_blank" >
Learn more
</a>
</p>
</div>``<!--``hero-unit
</div>``<!--``span12
</div>``<!--``row-fluid
</div>``<!--``content
</div>``<!--``span12
</div>``<!--``row-fluid
这是来自 1-bootstrap 的index.html的完整源代码:
<!DOCTYPE html>
<html``lang="en"
<head>
<link``type="text/css" rel="stylesheet" href="css/bootstrap.css"
</head>
<body >
<div``class="container-fluid"
<div``class="row-fluid"
<div``class="span12"
<div``id="content"
<div``class="row-fluid"
<div``class="span12"
<div``class="hero-unit"
<h1>``Welcome to Super Simple Backbone Starter Kit
<p>``This is your home page. To edit it just modify``<i>``index.html``</i>``file!
<p><a``class="btn btn-primary btn-large" href="http://twitter.github.com/bootstrap" target="_blank"``>??</a></p>
</div>``<!--``hero-unit
</div>``<!--``span12
</div>``<!--``row-fluid
</div>``<!--``content
</div>``<!--``span12
</div>``<!--``row-fluid
</div>``<!--``container-fluid
</body>
</html>
这个例子可以从 GitHub 公共库github.com/azat-co/fullstack-javascript 下载和拉取,在 01-bootstrap 文件夹 ( https://github.com/azat-co/fullstack-javascript/tree/master/01-bootstrap )下。如果你更喜欢看截屏,我在 YouTube 上录了一个( http://bit.ly/1RKx9uY )。
本视频和其他视频将带您完成书中概述的相同步骤。所以,如果你正在阅读这本书的印刷版本,不用担心。书中的信息足够了。
这里有一些其他有用的工具——CSS 框架和 CSS 预处理程序——值得一试:
- 指南针 : CSS 框架(
http://compass-style.org/) - 萨斯:CSS3 的扩展和模拟少(
http://sass-lang.com/) - 蓝图 : CSS 框架(
http://blueprintcss.org/) - 基础:响应式前端框架(
http://foundation.zurb.com/) - Bootswatch :定制 Twitter 引导主题集合(
http://bootswatch.com/) - WrapBootstrap :定制自举主题市场(
https://wrapbootstrap.com/)
要使用 Twitter Bootstrap 源文件,您需要使用 LESS 或 SASS (另一个类似 LESS 的 CSS 框架)。
较少的
LESS 是一种动态样式表语言。有时候,在这种情况下,少即是多,多即是少。浏览器无法解释更少的语法,因此必须以三种方式之一将更少的源代码编译成 CSS:
In the browser by the LESS JavaScript library On the server side by language or framework; for example, for Node.js there is the LESS module ( https://www.npmjs.com/package/less ) Locally on your machine by command line (installed with npm by running $ npm install -g less), WinLess ( http://winless.org/ ), LESS App ( http://incident57.com/codekit/index.html ), SimpLESS ( http://wearekiss.com/simpless ), or a similar app
浏览器选项适用于开发环境,但不太适合生产环境。
以下是一些在线编译工具:
- LESS2CSS (
http://less2css.org/):一个基于 Express.js 的基于浏览器的 LESS to CSS 转换器 - lessphp (
http://leafo.net/lessphp/):一个在线演示编译器 - 多普佛利 (
http://www.dopefly.com/LESS-Converter/less-converter.html):一种在线少转换器
LESS 具有变量、混合和操作符,使得开发人员可以更快地重用 CSS 规则。
较少变量
变量减少了冗余,并允许开发人员通过将它们放在一个规范的地方来快速更改值,我们知道在设计(和样式)中我们经常需要非常频繁地更改值。
我们有时会用一些更少的代码,用符号@标记变量,比如在@color中:
@color: #4D926F;
#header {
color:``@color
}
h2 {
color:``@color
}
这段代码将被编译成 CSS 中的等效代码:
#header {
color:``#4D926F
}
h2 {
color:``#4D926F
}
好处是,只需要在一个地方更新颜色值,而在 CSS 中只需要两个地方。这是最好的抽象。
更少的混音
这是关于混音功能的。混合的语法与创建类选择器的语法相同。例如,这是一个.border混音:
.border {
border-top:``dotted 1px black
border-bottom:``solid 2px black
}
#menu a {
color:``#111
.border;
}
.post a {
color:``red
.border;
}
转换成这个 CSS,其中的.border被替换为实际的样式,而不是名称:
.border {
border-top:``dotted 1px black
border-bottom:``solid 2px black
}
#menu a {
color:``#111
border-top:``dotted 1px black
border-bottom:``solid 2px black
}
.post a {
color:``red
border-top:``dotted 1px black
border-bottom:``solid 2px black
}
更有用的是给混音传递一个参数。这使得开发人员能够创建更加通用的代码。例如,.rounded-corners是一个可以根据参数radius的值改变大小的混音:
.rounded-corners (@radius: 5px) {
border-radius:``@radius
-webkit-border-radius:``@radius
-moz-border-radius:``@radius
}
#header {
.rounded-corners;
}
#footer {
.rounded-corners(10px);
}
该代码将编译成 CSS 格式:
#header {
border-radius:``5px
-webkit-border-radius:``5px
-moz-border-radius:``5px
}
#footer {
border-radius:``10px
-webkit-border-radius:``10px
-moz-border-radius:``10px
}
无论您使用不带参数的 mix-in 还是带多个参数的 mix-in,它们在创建抽象和实现更好的代码重用方面都非常出色。
较少操作
少支持运营。通过运算,我们可以对数字、颜色或变量执行数学函数。这对于大小、颜色和其他与数字相关的样式非常有用。
下面是一个在 LESS 中执行乘法和加法的运算符示例:
@the-border: 1px;
@base-color: #111;
@red: #842210;
#header {
color:``@base-color * 3
border-left:``@the-border
border-right:``@the-border * 2
}
#footer {
color:``@base-color + #003300
border-color:``desaturate(@red, 10%)
}
该代码在 CSS 中编译,编译器用变量和操作替换表达式的结果:
#header {
color:``#333333
border-left:``1px
border-right:``2px
}
#footer {
color:``#114411
border-color:``#7d2717
}
如您所见,LESS 显著提高了普通 CSS 的可重用性。在大型项目中,这可以节省时间,因为您可以创建更少的模块,并在多个应用中重用它们。
其他重要的少特征 ( http://lesscss.org/#docs )包括如下:
- 模式匹配
- 嵌套规则
- 功能
- 名称空间
- 范围
- 评论
- 进口
使用第三方 API (OpenWeatherMap)和 jQuery 的示例
引导您完成实施并演示项目的补充视频: http://bit.ly/1RKxyxA 。
这个例子纯粹是为了演示的目的。它不是后面章节中讨论的主要留言板应用的一部分。目标只是说明 jQuery、JSONP 和 REST API 技术的组合。
注意,这个例子使用了 OpenWeatherMap API 2.5。API 要求对 REST 调用进行身份验证(一个应用 ID)。您可以在 openweathermap.org/appid 获得所需的钥匙。API 文档可在 openweathermap.org/api 获得。
这个天气应用的想法是向您显示城市名称的输入字段以及公制和英制的按钮。一旦你输入城市名称并点击其中一个按钮,应用将从 OpenWeatherMap 获取天气预报。
在这个例子中,我们将使用 jQuery 的$.ajax()函数。它具有以下语法:
var request = $.ajax({
url: url,
dataType: ’jsonp’,
data: {q: cityName, appid: appId, units: units},
jsonpCallback: ’fetchData’,
type: ’GET’
}).fail(function(error){
console.error(error)
alert(’Error sending request’)
})
在刚刚显示的ajax()函数的代码片段中,我们使用了以下参数:
url是 API 的一个端点。dataType是我们期望从服务器得到的数据类型;例如,“json”、“xml”、“jsonp”(带前缀的 JSON—不支持 CORS 的服务器的格式)。data是要发送到服务器的数据。jsonpCallback是函数名,字符串格式,请求返回后调用;默认情况下,jQuery 会创建一个名称。type是请求的 HTTP 方法;比如“得”、“贴”。
还有一个链接的方法.fail,它有一个逻辑,当请求有错误(即失败)时做什么。
有关ajax()功能的更多参数和示例,请访问 api.jquery.com/jQuery.ajax 。
为了将我们的函数分配给用户触发的事件,我们需要使用 jQuery 库中的click函数。语法非常简单:
$(’#btn’).click(function() {
...
}
$(’#btn’)是一个 jQuery 对象,用btn的id指向 DOM 中的一个 HTML 元素。
为了确保我们想要访问和使用的所有元素都在 DOM 中,我们需要将所有 DOM 操作代码包含在以下 jQuery 函数中:
$(document).ready(function(){
...
}
这是动态生成的 HTML 元素的常见错误。它们在被创建并注入 DOM 之前是不可用的。
我们必须将按钮的事件处理程序放在$(document).ready()回调中。否则,代码可能会尝试将事件侦听器附加到不存在的 DOM 元素。$(document).ready()确保浏览器呈现所有的 DOM 元素。
$(document).ready(function(){
$(’.btn-metric’).click(function() {
prepareData(’metric’)
})
$(’.btn-imperial’).click(function() {
prepareData(’imperial’)
})
})
我们使用类而不是 ID,因为类更灵活(不能有多个同名的 ID)。下面是按钮的 HTML 代码:
<div``class="row"
<div``class="span6 offset1"
<input``type="button" class="btn-primary btn btn-metric" value="Get forecast in metric"
<div``class="span6 offset1"
<input``type="button" class="btn-danger btn btn-imperial" value="Get forecast in imperial"
</div>
<div``class="span3"
<p``id="info"
</div>
</div>
ID 为info的最后一个容器是我们放置预测的地方。
这个想法很简单:我们有按钮和事件侦听器,一旦用户单击按钮,它们就会做一些事情。前面提到的按钮调用prepareData()方法。这是它的定义:
var openWeatherAppId = ’GET-YOUR-KEY-AT-OPENWEATHERMAP’,
openWeatherUrl = ’http://api.openweathermap.org/data/2.5/forecast
var prepareData = function(units) {
var cityName = $(’#city-name’).val()
if (cityName && cityName != ’’){
cityName = cityName.trim()
getData(openWeatherUrl, cityName, openWeatherAppId, units)
}
else {
alert(’Please enter the city name’)
}
}
代码应该简单明了。我们从输入框中获取城市名称的值,检查它是否为空,并调用getDada(),这将向服务器发出 XHR 请求。您已经看到了一个$.ajax请求的例子。请注意,回调函数名为fetchData。这个函数将在浏览器从 OpenWeatherMap API 获得响应后被调用。不用说,我们必须按如下方式传递城市名称、应用 ID 和单位:
function getData (url, cityName, appId, units) {
var request = $.ajax({
url: url,
dataType: ’jsonp’,
data: {
q: cityName,
appid: appId,
units: units
},
jsonpCallback: ’fetchData’,
type: ’GET’
}).fail(function(error){
console.error(error)
alert(’Error sending request’)
})
}
JSONP 获取函数神奇地(多亏了 jQuery)通过注入脚本标记和将回调函数名附加到请求查询字符串来进行跨域调用。
此时,我们需要实现fetchData并用预测更新视图。console.log有助于查找响应的数据结构;也就是字段所在的位置。城市名称和国家将显示在预测上方,以确保找到的位置与我们在输入框中请求的位置相同。
function fetchData (forecast) {
console.log(forecast)
var html = ’’,
cityName = forecast.city.name,
country = forecast.city.country
现在,我们通过迭代预测并连接字符串来形成 HTML:
html += ’<h3> Weather Forecast for ’
+ cityName
+ ’, ’
+ country
+ ’</h3>’
forecast.list.forEach(function(forecastEntry, index, list){
html += ’<p>’
+ forecastEntry.dt_txt
+ ’: ’
+ forecastEntry.main.temp
+ ’</p>’
})
最后,我们为 ID 为log的 div 获取一个 jQuery 对象,并在 HTML 中注入城市名称和预测:
$(’#log’).html(html)
简单来说,有一个按钮元素触发了prepareData(),它调用了getData(),在它的回调中是fetchData()。如果您觉得这令人困惑,这里是index.html文件的完整代码:
<!DOCTYPE html>
<html``lang="en"
<head>
<link``type="text/css" rel="stylesheet" href="css/bootstrap.css"
<script``src="js/jquery.js" type="text/javascript"
<meta``name="viewport" content="width=device-width, initial-scale=1.0"
<script>
var openWeatherAppId = ’GET-YOUR-KEY-AT-OPENWEATHERMAP’,
openWeatherUrl = ’http://api.openweathermap.org/data/2.5/forecast
var``prepareData =``function
var cityName = $(’#city-name’).val()
if (cityName && cityName != ’’){
cityName = cityName.trim()
getData(openWeatherUrl, cityName, openWeatherAppId, units)
}
else {
alert(’Please enter the city name’)
}
}
$(document).ready(function(){
$(’.btn-metric’).click(function() {
prepareData(’metric’)
})
$(’.btn-imperial’).click(function() {
prepareData(’imperial’)
})
})
function getData (url, cityName, appId, units) {
var request = $.ajax({
url: url,
dataType: ’jsonp’,
data: {
q: cityName,
appid: appId,
units: units
},
jsonpCallback: ’fetchData’,
type: ’GET’
}).fail(function(error){
console.error(error)
alert(’Error sending request’)
})
}
function fetchData (forecast) {
console.log(forecast)
var html = ’’,
cityName = forecast.city.name,
country = forecast.city.country
html += ’<h3> Weather Forecast for ’
+ cityName
+ ’, ’
+ country
+ ’</h3>’
forecast.list.forEach(function(forecastEntry, index, list){
html += ’<p>’
+ forecastEntry.dt_txt
+ ’: ’
+ forecastEntry.main.temp
+ ’</p>’
})
$(’#log’).html(html)
}
</script>
</head>
<body>
<div``class
<div``class
<div``class
<h2>Weather App</h2>
<p>Enter city name to get the weather forecast</p>
</div>
<div class="span6 offset1"><input class="span4" type="text" placeholder="Enter the city name" id="city-name" value=""/>
</div>
</div>
<div``class
<div``class``="span6 offset1"><input type="button"``class
<div class="span6 offset1"><input type="button" class="btn-danger btn btn-imperial" value="Get forecast in imperial"/>
</div>
<div class="span3">
<p id="info"></p>
</div>
</div>
<div``class
<div``class
<div id="log">Nothing to show yet</div>
</div>
</div>
<div class="row">
<hr/>
<p>Azat Mardan (<a href="``http://twitter.com/azat_co">@azat_co</a>)</p
</div>
</div>
</body>
</html>
试着启动它,看看它是否在本地 HTTP 服务器上工作(只需在浏览器中打开index.html)。如果没有 HTTP 服务器,它应该无法工作,因为它依赖于 JSONP 技术。你可以得到http-static或http-server命令行工具,如第二章所述。
源代码可以在 0 2-weather 文件夹和 GitHub ( github)上找到。com/azat-co/full stack-JavaScript/tree/master/02-weather)。YouTube 上有一个截屏视频,它会带你完成实现并演示该应用。
此示例是用 OpenWeatherMap API v2.5 构建的,可能不适用于更高版本。此外,您还需要名为 app ID 的 API 键。您可以在 openweathermap.org/appid 获得所需的钥匙。如果你觉得必须要有一个工作实例,请将你的反馈提交到 GitHub 资源库,以获得本书的项目( https://github.com/azat-co/fullstack-javascript )。
jQuery 是一个很好的从 RESTful 服务器获取数据的库。有时我们不仅仅是从服务器上读取数据;我们也想写它。通过这种方式,信息得以保存,并可以在以后被访问。Parse.com 将允许你没有摩擦地保存你的数据。
Parse.com
引导您完成实施并演示项目的补充视频: http://bit.ly/1SU8imX 。
Parse.com(parse。com )是一个可以替代数据库和服务器的服务。它最初是作为支持移动应用开发的手段出现的。然而,有了 REST API 和 JavaScript SDK,Parse.com 可以在任何 web 和桌面应用中用于数据存储(以及更多),这使得它成为快速原型开发的理想选择。
去 Parse.com 注册一个免费账户。创建一个应用,复制应用 ID、REST API 键和 JavaScript 键。我们需要这些钥匙来打开我们在 Parse.com 的收藏。请注意数据浏览器选项卡,因为在那里您可以看到您的收藏和项目。
我们将创建一个简单的应用,使用 Parse.com JavaScript SDK 将值保存到集合中。我们的应用将由一个index.html文件和一个app.js文件组成。下面是我们项目文件夹的结构:
/03-parse-sdk
-index.html
-app.js
-jquery.js
/css
-boostrap. css
该示例位于 GitHub ( github)上的 03-parse-sdk 文件夹中。com/azat-co/full stack-JavaScript/tree/master/03-parse-SDK),但是鼓励您从头开始键入自己的代码。首先,创建index.html文件:
<html``lang="en"
<head>
从本地文件中包含缩小的 jQuery v2.1.4 库(可以下载并保存到文件夹中):
<script
type="text/javascript"
src=
"jquery.js" >
</script>
包括来自解析 CDN 位置的 Parse.com JavaScript SDK 库 v1.6.7:
<script
src="// www.parsecdn.com/js/parse-1.6.7.min.js "
</script>
包括我们的app.js文件和 Twitter Bootstrap v4.0.0-alpha:
<script``type="text/javascript" src="app.js"
<link``type="text/css" rel="stylesheet" href="css/bootstrap.css"
</head>
<body>
<!--``We’ll do something here
</body>
</html>
HTML 页面的<body>由<textarea>元素组成。我们将用它来输入 JSON:
<body>
<div``class="container-fluid"
<div``class="row-fluid"
<div``class="span12"
<div``id="content"
<div``class="row-fluid"
<div``class="span12"
<div``class="hero-unit"
<h1>``Parse JavaScript SDK demo
<textarea``cols="60" rows="7"``>
"name": "John",
"text": "hi"
} </textarea>
<textarea>的缩进看起来不正常,因为这个元素保留了空白,当我们将该字符串处理成 JSON 时,我们不想要它。
在输入区域之后,有一个按钮将触发保存到 Parse.com:
<p><a``class="btn btn-primary btn-large btn-save"``>``Save object
<pre``class="log"
Go to``<a``href="https://parse.com/apps/" target="_blank"``>``Parse.com``</a>``to check the data.
</div>``<!--``hero-unit
</div>``<!--``span12
</div>``<!--``row-fluid
</div>``<!--``content
</div>``<!--``span12
</div>``<!--``row-fluid
</div>``<!--``container-fluid
</body>
</html>
创建app.js文件并使用$(document).ready函数来确保 DOM 已准备好进行操作:
$(document).ready(function() {
将parseApplicationId和parseJavaScriptKey更改为 Parse.com 应用仪表板中的值(您需要注册该服务):
var parseApplicationId = ’GET-YOUR-KEYS-AT-PARSE.COM’
var parseJavaScriptKey = ’GET-YOUR-KEYS-AT-PARSE.COM’
因为我们已经包含了 Parse JavaScript SDK 库,所以我们现在可以访问全局对象Parse。我们用键初始化一个连接,并创建一个对Test集合的引用:
Parse.initialize(parseApplicationId, parseJavaScriptKey)
var Test = Parse.Object.extend(’Test’)
var test = new Test()
这个简单的代码将把一个带有键name和text的对象保存到 Parse.comTest集合中:
var Test = Parse.Object.extend(’Test’)
var test = new Test()
$(’.btn-save’).click(function(){
接下来的几条语句处理从<textarea>获取 JSON,并将其解析成普通的 JavaScript 对象。try/catch非常关键,因为 JSON 的结构非常严格。你不能有任何额外的符号。每次出现语法错误,都会破坏整个应用。因此,我们需要考虑错误的语法:
try {
var data = JSON.parse($(’textarea’).val())
} catch (e) {
alert(’Invalid JSON’)
}
if (!data) return false
方便的是,save()方法接受回调参数success和error,就像jQuery.ajax()函数一样。要得到确认,我们只需查看页面上的log容器(<pre class="log"></pre>):
success: function(object) {
console.log(’Parse.com object is saved: ’, object)
$(’.log’).html(JSON.stringify(object, null, 2))
// Alternatively you could use alert(’Parse.com object is saved’)
},
了解我们保存对象失败的原因很重要:
error: function(object) {
console.log(’Error! Parse.com object is not saved: ’, object)
}
})
})
})
这样你就不必点击 Github 链接(或从书中键入)来查找app.js文件的完整源代码,我在这里提供了它:
$(document).ready(function() {
var parseApplicationId = ’GET-YOUR-KEYS-AT-PARSE.COM’
var parseJavaScriptKey = ’GET-YOUR-KEYS-AT-PARSE.COM’
// Change parseApplicationId and parseJavaScriptKey to values from Parse.com application dashboard
Parse.initialize(parseApplicationId, parseJavaScriptKey)
var Test = Parse.Object.extend(’Test’)
var test = new Test()
$(’.btn-save’).click(function(){
try {
var data = JSON.parse($(’textarea’).val())
} catch (e) {
alert(’Invalid JSON’)
}
if (!data) return false
test.save(data, {
success: function(object) {
console.log(’Parse.com object is saved: ’, object)
$(’.log’).html(JSON.stringify(object, null, 2))
},
error: function(object) {
console.log(’Error! Parse.com object is not saved: ’, object)
}
})
})
})
对于这种方法,我们需要使用 Parse.com 仪表板中的 JavaScript SDK 键。对于 jQuery 示例,我们将使用来自同一 web 页面的 REST API 键。
要运行该应用,请在项目文件夹中启动本地 web 服务器,并在浏览器中导航到该地址(如http://localhost:8080)。如果你从 Parse.com 得到一个 401 未授权错误,那可能是因为你有错误的 API 密匙。
如果一切正常,您应该能够在 Parse.com 的数据浏览器中看到填充了值“John”和“hi”的Test。此外,您应该看到带有新创建的 ID 的正确消息。Parse.com 自动创建对象 id 和时间戳,这在我们的留言板应用中非常有用。
Parse.com 还为 Hello World 应用提供了详细的说明,这些说明可以在新项目( https://parse.com/apps/quickstart#js/blank )和现有项目( https://parse.com/apps/quickstart#js/existing )的快速入门指南部分中找到。
让我们继续讨论留言板应用。
Parse.com 总览留言板
引导您完成实施并演示项目的补充视频: http://bit.ly/1SU8pyS 。
留言板将由一个输入框、一个消息列表和一个发送按钮组成。我们需要显示现有消息的列表,并能够提交新消息。我们现在将使用 Parse.com 作为后端,稍后使用 MongoDB 切换到 Node.js。
你可以在 Parse.com 获得一个免费账户。JavaScript 指南在 https://parse.com/docs/js_guide 可用,JavaScript API 在 https://parse.com/docs/js/ 可用。
注册 Parse.com 后,转到仪表板并创建一个新的应用(如果您还没有这样做)。复制您新创建的应用的应用 ID 和 JavaScript 密钥以及 REST API 密钥。你以后会需要它们的。有几种方法可以使用 Parse.com:
- REST API:我们将在 jQuery 示例中使用这种方法。
- JavaScript SDK:我们刚刚在前面的测试示例中使用了这种方法,稍后我们将在 Backbone.js 示例中使用它。
REST API 是一种更通用的方法。Parse.com 提供了端点,我们可以用 jQuery 库中的$.ajax()方法请求这些端点。可用 URL 和方法的描述可以在 parse.com/docs/rest 找到。
带有 Parse.com 的留言板:REST API 和 jQuery 版本
完整的代码可以在04-board-parse-rest ( github 中找到。com/azat-co/full stack-JavaScript/tree/master/04-board-parse-rest)文件夹,但我们鼓励您先尝试编写自己的应用。
我们将使用 Parse.com 的 REST API 和 jQuery。Parse.com 支持不同的源域 AJAX 调用,所以我们不需要 JSONP。
当您决定在不同的域上部署您的后端应用(它将充当 Parse.com 的替代品)时,您需要在前端使用 JSONP,或者在后端使用定制的 CORS 头文件。这一主题将在本书的后面介绍。
现在,应用的结构应该如下所示:
index.html
css/bootstrap.min.css
css/style.css
js/app.js
img/spinner.gif
让我们为留言板应用创建一个可视化表示。我们只想按时间顺序显示带有用户名的消息列表。因此,一个表格就足够了,我们可以动态地创建<tr>元素,并在获得新消息时不断地插入它们。
用以下内容创建一个简单的 HTML 文件index.html:
- 包含 JS 和 CSS 文件
- 具有 Twitter 引导的响应结构
- 信息表
- 新邮件的表单
让我们从head和依赖项开始。我们将包括 CDN jQuery、local app.js、local minified Twitter Bootstrap 和自定义样式表style.css:
<!DOCTYPE html>
<html``lang="en"
<head>
<script``src="js/jquery.js" type="text/javascript" language="javascript"
<script``src="js/app.js" type="text/javascript" language="javascript"
<link``href="css/bootstrap.min.css" type="text/css" rel="stylesheet"
<link``href="css/style.css" type="text/css" rel="stylesheet"
<meta``name="viewport" content="width=device-width, initial-scale=1"
</head>
body 元素将具有由类container-fluid和row-fluid定义的典型 Twitter Boostrap scaffolding 元素:
<body>
<div``class="container-fluid"
<div``class="row-fluid"
<h1>``Message Board with Parse REST API
消息表是空的,因为我们将从 JS 代码中以编程方式填充它:
<table``class="table table-bordered table-striped"
<caption>``Messages
<thead>
<tr>
<th>
Username
</th>
<th>
Message
</th>
</tr>
</thead>
<tbody>
<tr>
<td``colspan="2"``><img``src="img/spinner.gif" width="20"
</tr>
</tbody>
</table>
</div>
另一行是我们的新消息表单,其中的发送按钮使用了 Twitter 引导类btn和btn-primary:
<div``class="row-fluid"
<form``id="new-user"
<input type="text" name="username"
placeholder="Username" />
<input type="text" name="message"
placeholder="Message" />
<a``id="send" class="btn btn-primary"``>``SEND
</form>
</div>
</div>
</body>
</html>
该表将包含我们的消息,该表单将为新消息提供输入。
现在我们要写三个主要函数:
getMessages(): The function to get the messages updateView(): The function to render the list of messages $(’#send’).click(...): The function that triggers sending a new message
为了简单起见,我们将所有的逻辑放在一个文件app.js中。当然,当你的项目越来越大时,根据功能来分离代码是一个好主意。
用您自己的值替换这些值,并注意使用 REST API 键(不是前面示例中的 JavaScript SDK 键):
var parseID=’YOUR_APP_ID’
var parseRestKey=’YOUR_REST_API_KEY’
先说document.ready。它将具有获取消息的逻辑,并定义发送按钮的点击事件:
$(document).ready(function(){
getMessages()
$(’#send’).click(function(){
让我们保存按钮对象:
var $sendButton = $(this)
我们应该显示一个微调图像(“正在加载...”)按钮上,因为请求可能需要一些时间,我们希望用户看到我们的应用正在工作,而不是无缘无故地冻结。
$sendButton.html(’<img src="img/spinner.gif" width="20"/>’)
var username = $(’input[name=username]’).val()
var message = $(’input[name=message]’).val()
当我们提交一个新消息(POST 请求)时,我们用jQuery.ajax函数进行 HTTP 调用。在 api.jquery.com/jQuery.ajax 可获得ajax功能的完整参数列表。最重要的是 URL、头和类型参数。
$.ajax({
url: ’https://api.parse.com/1/classes/MessageBoard
headers: {
’X-Parse-Application-Id’: parseAppID,
’X-Parse-REST-API-Key’: parseRestKey
},
contentType: ’application/json’,
数据的类型是 JSON:
dataType: ’json’,
processData: false,
data: JSON.stringify({
’username’: username,
’message’: message
}),
type: ’POST’,
success: function() {
console.log(’sent’)
假设我们的 POST 请求 Parse 保存了新消息(success),我们现在希望获得包含我们的消息的更新的消息列表,并使用文本替换微调图像,就像有人单击按钮之前一样:
getMessages()
$sendButton.html(’SEND’)
},
error: function() {
console.log(’error’)
$sendButton.html(’SEND’)
}
})
总的来说,单击 Send 按钮将向 Parse.com REST API 发送一个 POST 请求,然后在成功响应时,获得调用getMessages()函数的消息。
从我们的远程 REST API 服务器获取消息的getMessages()方法也使用了jQuery.ajax函数。该 URL 包含收藏集的名称(MessageBoard)和一个查询字符串参数,该参数将限制设置为 1,000:
function getMessages() {
$.ajax({
url: ’https://api.parse.com/1/classes/MessageBoard?limit=1000
我们需要在头中传递密钥:
headers: {
’X-Parse-Application-Id’: parseAppID,
’X-Parse-REST-API-Key’: parseRestKey
},
contentType: ’application/json’,
dataType: ’json’,
type: ’GET’,
如果请求成功完成(状态200/ok或类似),我们调用updateView函数:
success: function(data) {
console.log(’get’)
updateView(data)
},
error: function() {
console.log(’error’)
}
})
}
然后,在成功响应时,它将调用updateView()函数,该函数清除表tbody,并使用$.each jQuery 函数( api.jquery.com/jQuery.each )遍历响应的结果。
该函数呈现我们从服务器获得的消息列表:
function updateView(messages) {
我们使用 jQuery 选择器.table tbody创建一个引用该元素的对象。然后我们清理该元素的所有 innerHTML:
var table=$(’.table tbody’)
table.html(’’)
我们使用jQuery.each函数遍历每条消息:
$.each(messages.results, function (index, value) {
var trEl =
以下代码以编程方式创建 HTML 元素(以及这些元素的 jQuery 对象):
(’<tr><td>’
+ value.username
+ ’</td><td>’
+ value.message +
’</td></tr>’)
从某种意义上来说,trEl是一个字符串,包含留言板中每条消息或每一行的 HTML。下一行将表的tbody元素追加到我们的行中:
table.append(trEl)
})
console.log(messages)
}
下面是使用 jQuery 动态创建 HTML 元素(例如,div)的另一种方法:
$(’<div>’)
以下是完整的app.js供您参考:
var parseAppID=’your-parse-app-id’
var parseRestKey=’your-rest-api-key’
$(document).ready(function(){
getMessages()
$(’#send’).click(function(){
var $sendButton = $(this)
$sendButton.html(’<img src="img/spinner.gif" width="20"/>’)
var username = $(’input[name=username]’).val()
var message = $(’input[name=message]’).val()
$.ajax({
url: ’https://api.parse.com/1/classes/MessageBoard
headers: {
’X-Parse-Application-Id’: parseAppID,
’X-Parse-REST-API-Key’: parseRestKey
},
contentType: ’application/json’,
dataType: ’json’,
processData: false,
data: JSON.stringify({
’username’: username,
’message’: message
}),
type: ’POST’,
success: function() {
console.log(’sent’)
getMessages()
$sendButton.html(’SEND’)
},
error: function() {
console.log(’error’)
$sendButton.html(’SEND’)
}
})
})
})
function getMessages() {
$.ajax({
url: ’https://api.parse.com/1/classes/MessageBoard?limit=1000
headers: {
’X-Parse-Application-Id’: parseAppID,
’X-Parse-REST-API-Key’: parseRestKey
},
contentType: ’application/json’,
dataType: ’json’,
type: ’GET’,
success: function(data) {
console.log(’get’)
updateView(data)
},
error: function() {
console.log(’error’)
}
})
}
function updateView(messages) {
var table=$(’.table tbody’)
table.html(’’)
$.each(messages.results, function (index, value) {
var trEl=(’<tr><td>’
+ value.username
+ ’</td><td>’
+ value.message
+ ’</td></tr>’)
table.append(trEl)
})
console.log(messages)
}
尝试使用本地 HTTP 服务器运行代码。您应该看到消息(显然,第一次应该没有消息),并通过单击按钮能够发布新消息。
如果您需要做的只是在本地机器上开发应用,这没问题,但是将它部署到云上呢?要做到这一点,我们首先需要用 Git 应用版本控制。
推送至 GitHub
向您介绍项目部署的补充视频(Git 和 Heroku 部分从 9 分 57 秒开始): http://bit.ly/1SU8K4I 。
要创建 GitHub 存储库,请进入 github.com ,登录并创建一个新的存储库。会有一个 SSH 地址;复制它。在您的终端窗口中,导航到您想要推送到 GitHub 的项目文件夹。
Create a local Git and .git folder in the root of the project folder: $ git init Add all of the files to the repository and start tracking them: $ git add . Make the first commit: $ git commit -am "initial commit" Add the GitHub remote destination: $ git remote add your-github-repo-ssh-url It might look something like this: $ git remote add origin git@github.com:azat-co/simple-message-board.git Now everything should be set to push your local Git repository to the remote destination on GitHub with the following command: $ git push origin master You should be able to see your files at github.com under your account and repository.
稍后,当您对文件进行更改时,没有必要重复所有这些步骤。只需执行:
$ git add .
$ git commit -am "some message"
$ git push origin master
如果没有要开始跟踪的新的未跟踪文件,请使用以下命令:
$ git commit -am "some message"
$ git push origin master
要包括单个文件的更改,请运行:
$ git commit filename -m "some message"
$ git push origin master
要从 Git 存储库中删除文件,请使用:
$ git rm filename
有关更多 Git 命令,请参见:
$ git --help
使用 Windows Azure 或 Heroku 部署应用就像将代码和文件推送到 GitHub 一样简单。最后三个步骤(4–6)将替换为不同的远程目标(URL)和不同的别名。
部署到 Windows Azure
使用此过程,您应该能够使用 Git 部署到 Windows Azure。
Go to the Windows Azure Portal at https://windows.azure.com/ 1, log in with your Live ID and create a web site if you haven’t done so already. Enable Set Up Git Publishing by providing a user name and password (they should be different from your Live ID credentials). Copy your URL somewhere. Create a local Git repository in the project folder that you would like to publish or deploy: $ git init Add all of the files to the repository and start tracking them: $ git add . Make the first commit: $ git commit -am "initial commit" Add Windows Azure as a remote Git repository destination: $ git remote add azure your-url-for-remote-repository In my case, this command looked like this: $ git remote add > azure https://azatazure@azat.scm.azurewebsites.net/azat.git Push your local Git repository to the remote Windows Azure repository, which will deploy the files and application: $ git push azure master
与 GitHub 一样,当您稍后更新文件时,没有必要重复前面的几个步骤,因为我们已经应该在项目文件夹的根目录中有一个以.git文件夹形式的本地 Git 存储库。
部署到 Heroku
向您介绍项目部署的补充视频(Git 和 Heroku 部分从 9 分 57 秒开始): http://bit.ly/1SU8K4I 。
唯一的主要区别是 Heroku 使用 Cedar Stack,它不支持静态项目,包括普通的 HTML 应用,如我们的 Parse.com 测试应用或 Parse.com 版本的留言板应用。我们可以使用一个“假”的 PHP 项目来克服这个限制。在项目文件夹中创建一个与index.html处于同一级别的文件index.php,您希望将该文件发布或部署到 Heroku,其内容如下:
<?php``echo file_get_contents(’index.html’);
为了方便起见,index.php文件已经包含在04-board-parse-rest中。
有一种更简单的方法可以用 Cedar Stack 在 Heroku 上发布静态文件,这在 Heroku Cedar 上的 post Static 站点中有所描述。heroku-cedar 河畔 static-sites。html 。要让 Cedar Stack 处理静态文件,您只需在项目文件夹中键入并执行以下命令:
$``touch
$``echo``’php_flag engine off’``>
或者,您可以使用 Ruby Bamboo 堆栈。在这种情况下,我们需要以下结构:
-project folder
-config.ru
/public
-index.html
-/css
app.js
...
index.html中到 CSS 和其他资产的路径应该是相对的,也就是’css/style.css’。config.ru文件应该包含以下代码:
use Rack::Static,
:urls => ["/stylesheets", "/images"],
:root => "public"
run lambda { |env|
[
200,
{
’Content-Type’ => ’text/html’,
’Cache-Control’ => ’public, max-age=86400’
},
File.open(’public/index.html’, File::RDONLY)
]
}
更多详情可以参考 devcenter.heroku.com/articles/static-sites-on-heroku 。
一旦您有了 Cedar Stack 或 Bamboo 的所有支持文件,请遵循以下步骤:
Create a local Git repository and .git folder if you haven’t done so already: $ git init Add files: $ git add . Commit files and changes: $ git commit -m "my first commit" Create the Heroku Cedar Stack application and add the remote destination: $ heroku create If everything went well, it should tell you that the remote has been added and the app has been created, and give you the app name. To look up the remote type and execute (optional): $ git remote show Deploy the code to Heroku with: $ git push heroku master Terminal logs should tell you whether or not the deployment went smoothly. To open the app in your default browser, type: $ heroku open or just go to the URL of your app, something like http://yourappname-NNNN.herokuapp.com . To look at the Heroku logs for this app, type: $ heroku logs To update the app with the new code, repeat the following steps only: $ git add -A $ git commit -m "commit for deploy to heroku" $ git push -f heroku
每次使用命令$ heroku create创建一个新的 Heroku 应用时,您都会被分配一个新的应用 URL。
更新和删除消息
根据 REST API,对象的更新通过PUT方法执行,删除通过DELETE方法执行。只要我们提供一个想要对其执行操作的对象的 ID,这两个操作都可以用我们对GET和POST使用的同一个jQuery.ajax函数轻松执行。
摘要
这一章很难。希望您对 JSON、AJAX 和跨域调用有所了解。记住,当访问服务器时,你需要确保它们支持 CORS 或 JSONP。
我们已经介绍了一些最基本的特性,并使用 Parse 来持久化数据。我们还使用 Git 版本系统将我们的应用部署到云中。