summaryrefslogtreecommitdiff
path: root/talermerchantdemos/blog/articles/zh/javascript-trap.html
blob: 19ac7000fed88fb49241c82ea6af5f9ade481552 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
<!--#set var="ENGLISH_PAGE" value="/philosophy/javascript-trap.en.html" -->

<!--#include virtual="/server/header.zh-cn.html" -->
<!-- Parent-Version: 1.90 -->

<!-- This file is automatically generated by GNUnited Nations! -->
<title>JavaScript的陷阱</title>

<!--#include virtual="/philosophy/po/javascript-trap.translist" -->
<!--#include virtual="/server/banner.zh-cn.html" -->
<h2>JavaScript的陷阱</h2>

<p><a href="http://www.stallman.org/">Richard Stallman</a> 著</p>

<p><strong>你可能每天都在自己的电脑上运行非自由软件却毫不知情&mdash;&mdash;通过使用你的浏览器。</strong></p>

<!-- any links that used to point to the appendices should point to
     free-your-javascript.html instead.  -->
<blockquote>
<p>网络管理员:有<a
href="/software/librejs/free-your-javascript.html">好几种方法</a>可以指示网站的JavaScript程序的许可证。</p>
</blockquote>

<p>在自由软件社区,<a
href="/philosophy/free-software-even-more-important.html">非自由软件会侵害其用户</a>的概念大家都很熟悉。有些人会拒绝在电脑上使用任何专有软件,以此来捍卫自己的自由。还有许多人意识到非自由并拒绝那些程序。</p>

<p>许多用户知道浏览器要求安装的插件有此问题,因为它们可能是自由软件,也可能是非自由软件。但是浏览器也会运行不要求你许可的其他非自由软件,甚至也不告诉你&mdash;&mdash;网页带有或链接了哪些程序。这些程序多数是用JavaScript编写的,虽然其他语言也是可以的。</p>

<p>JavaScript(正式名称是ECMAScript,但是很少有人用了)曾经用于不重要的网页装饰,比如可爱但是并不重要的导航和显示功能。可以认为这些只是HTML标记语言的扩展,而不是真正的软件,这样就可以忽略它的问题。</p>

<p>一些网站仍然这样使用JavaScript,但是有一些网站用它作为完成任务的主要程序。例如,Google
Docs会尝试在你的电脑里下载大约500k字节的JavaScript程序,该程序使用一种我们称之为模糊脚本(Obfuscript)的紧密格式。这种格式删除了源代码里有助阅读的空格和注释,并将原来有意义的方法名称替换为任意的短名称,这样人们就无法直接看出这些方法原来的意义。</p>

<p><a
href="/philosophy/free-sw.html">自由软件定义</a>的内容包含着用户可以访问程序的源代码。一个程序的源代码应该是有利于修改程序的形式&mdash;包括有利阅读的空格和分行、解释性注释和有意义的名称。这种紧密格式不是源代码,而只是毫无用处的源代码替代品;其源代码并没有提供给用户,因而用户无法了解该程序;该程序是非自由的。</p>

<p>除了是非自由软件,许多这种程序是<em>恶意软件</em>,因为它们<a
href="http://github.com/w3c/fingerprinting-guidance/issues/8">嗅探用户</a>。更恶劣的是,有些站点使用服务来记录<a
href="https://freedom-to-tinker.com/2017/11/15/no-boundaries-exfiltration-of-personal-data-by-session-replay-scripts/">用户浏览该页面时的所有行为</a>。该服务本来应该&ldquo;修改&rdquo;记录以抹去网站不该获得的一些敏感数据。但是,即使该功能能够可靠的实施,该服务的整体目的也是给予该网站它不应该获得的个人数据。</p>

<p>浏览器一般不会告诉你它们什么时候会加载JavaScript程序。有些浏览器提供了完全禁用JavaScript的方法,可是即使你知道有问题,你还是需要花很多精力去确认这些非自由软件并拦截它们。然而,就连自由软件社区的大多数用户都不知道这个有问题;而浏览器的沉默也好似在掩盖这个问题。</p>

<p>可以把JavaScript程序发布为自由软件,使用自由软件许可证发布其源代码就行。如果该程序是自给自足的&mdash;&mdash;如果它的功能和目的独立于它所应用的网站&mdash;&mdash;这就没问题;你可以将其拷贝到你的电脑,修改它,使用浏览器加载它并运行它。但是这并不是其通常的情形。</p>

<p>通常情况下,JavaScript程序会和特定的网页或网站一起工作,而那个网页或网站有了这个程序才能正常工作。这就出现了另一个问题:即使有源程序,浏览器也无法运行你修改的版本,除非你使用原来的版本访问特定的网站或网页。这个效果和tivoization<sup><a
href="#TransNote1">1</a></sup>类似,虽然从根本上不是那么难以解决。</p>

<p>JavaScript不是网站发送到用户的程序使用的唯一语言。Flash支持用一种扩展的JavaScript语言编程;如果我们有足够完整的自由Flash播放器,我们就可以对付非自由Flash程序带来的问题。Silverlight似乎也和Flash一样创建一些程序,可能更糟,因为微软使用它作为非自由编解码器的平台。自由的Silverlight替代不能为自由世界正常工作,除非它还带有自由的编解码替代。</p>

<p>Java小程序<sup><a
href="#TransNote2">2</a></sup>也会在浏览器里运行,也就有同样的问题。一般来说,各种小程序系统都有这样的问题。创建一个运行小程序的自由环境仅仅是让我们能够看到这个问题。</p>

<p>理论上能够使用HTML和CSS编程,但是实际上它不方便而且受限制;最多只是展示一些令人惊奇的黑客编程技巧。这些程序理应是自由的,不过CSS在2019年还不是影响用户自由的严重问题。</p>

<p>已经有一个强大的运动,它号召网站只使用自由(有的人叫&quot;开放&quot;)的格式和协议来通信;就是说,它们的文档应该公开,而且任何人都有自由来实现。然而,当网页带有JavaScript程序时,这个标准就不够了。JavaScript本身,作为一种格式,是自由的,而且在网站上使用JavaScript并不必然是坏事。然而,正如以上所看到的,它也不必然就是好事&mdash;&mdash;如果JavaScript程序是非自由软件。当网站将程序转移到用户,程序只是由有文档、不受限制的语言编写并不足够;该程序必须也是自由的。&ldquo;只许把自由软件转移到用户&rdquo;必须成为网站行为规范的准则。</p>

<p>不动声色地加载和运行非自由软件只是&quot;网络应用&quot;带来的诸多问题之一。&quot;网络应用&quot;这一术语就是用来抹杀用户软件和服务器软件的根本区别。它可以指运行在浏览器里的特定客户端软件;它也可以指特定的服务器软件;它还可以指和特定服务器软件紧密协作的客户端软件。客户端和服务器端有不同的道德问题,即使它们如此紧密地协作,以至于可以说它们是一个软件的不同部分。本文只讨论客户端软件的问题。我们会分开讨论服务器端的软件。</p>

<p>实际操作中,我们应该如何对付网站上非自由、非平凡的JavaScript程序带来的问题呢?第一步就是避免运行它。</p>

<p>什么是我们说的&quot;非平凡&quot;呢?它表示的是程度,所以它是指设计一种简明的标准来获得好的结果,而不是去寻求唯一正确的答案。</p>
<p>
我们目前的标准认为一个JavaScript程序是非平凡的,如果它满足以下任一条件:</p>

<ul>
  <li>该程序引用一个外部的脚本(来自另一个页面)。</li>

  <li>该程序声明的数组超过了50个元素。</li>

  <li>该程序定义的主体(函数或方法)会做调用基本函数以外的调用。</li>

  <li>该程序定义的主体带有3个以上的条件判断或循环结构。</li>

  <li>除了定义之外,页面的代码调用了该页面上间隔很远的非基本函数。</li>

  <li>除了定义之外,页面代码带有3个以上的条件判断或循环结构(两个结构的总和超过3)。</li>

  <li>该程序调用了 <b>eval</b>。</li>

  <li>该程序有 Ajax 调用。</li>

  <li>该程序使用带有方括号形式的动态对象属性访问,就像<b><em>object</em>[<em>property</em>]</b>这样。</li>

  <li>该程序修改了 DOM。</li>
  
  <li>该程序要么使用动态JavaScript结构,这些结构在不了解该程序的情况下很难分析,要么该程序和使用这些结构的脚本一起加载。具体情况是程序使用除了诸如带有方法(<b>Obj.write</b>,
<b>Obj.createElement</b>等)之外的字符串字面量。</li>
</ul>

<p>我们如何判别JavaScript代码是否是自由的?在<a
href="/licenses/javascript-labels.html">另一篇文章</a>中,我们提议了一种方法,它指出网页带有的非平凡JavaScript程序可以使用风格化的注释来表达获得其源代码的URL,也可以表达其许可证。</p>

<p>最后,我们需要修改自由的浏览器,使它们可以探测并拦截网页上非平凡、非自由的JavaScript。<a
href="/software/librejs/">LibreJS</a>程序就可以探测到你访问的网页上的非自由、非平凡的JavaScript,并拦截之。LibreJS包含在IceCat浏览器中,也可以作为Firefox的附加组件。</p>

<p>浏览器用户还需要方便的工具来指定需要使用的JavaScript代码,<em>而不是</em>使用网页上的JavaScript代码。(指定的代码可以是完全的替代,也可以是页面上的自由JavaScript程序的修改版。)Greasemonkey已经快能够做到这一点,但是还没有,因为它不能保证在页面上的JavaScript程序运行之前就做出修改。使用本地的代理可以工作,但是作为真正的解决方案还是太不方便。我们需要构建一个可靠和方便的解决方案,也要构建一个分享修改方法的网站。GNU工程愿意推荐那些只致力于分享自由修改方法的网站。</p>

<p>这些措施使网页带有的JavaScript程序变成实际和真正意义上的自由软件成为可能。JavaScript就不再是阻碍我们自由的特别障碍&mdash;就象现在的C和Java那样。我们将来能够拒绝、甚至替换掉非自由和非平凡的JavaScript程序,就像我们拒绝和替换那些以通常形式安装的非自由软件包一样。那时,我们就能够开始让网站提供自由JavaScript程序的活动了。</p>

<p>与此同时,在一种情形下运行非自由JavaScript程序是可以接受的:使用它来向网站操作员抱怨该网站应该移除JavaScript代码或者使它自由。请不要犹豫,你可以暂时启用JavaScript做这件事&mdash;之后别忘了再禁用它就好。</p>

<!-- any links that used to point to the appendices should point to
     free-your-javascript.html instead.  -->
<blockquote>
<p>网络管理员:有<a
href="/software/librejs/free-your-javascript.html">好几种方法</a>可以指示网站的JavaScript程序的许可证。</p>
</blockquote>

<p><strong>致谢:</strong>我感谢<a href="/people/people.html#mattlee">Matt Lee</a>和<a
href="http://ejohn.org">John Resig</a>,他们帮助我们定义了我们提议的标准,还感谢David
Parunakian提醒我关注此问题。</p>

<div class="translators-notes">

<!--TRANSLATORS: Use space (SPC) as msgstr if you don't have notes.-->
<h3>译注</h3>
<ol>
<li
id="TransNote1">tivoization,是一种电脑工具,它包含在GPL软件内但你却不能修改它,因为一旦发现软件遭到修改它就会自动关闭。</li>
<li id="TransNote2">applet,是一种小程序,可以在特定的环境下独立运行。</li>
</ol></div>
</div>

<!-- for id="content", starts in the include above -->
<!--#include virtual="/server/footer.zh-cn.html" -->
<div id="footer">
<div class="unprintable">

<p>请将有关自由软件基金会(FSF)&amp;GNU的一般性问题发送到<a
href="mailto:gnu@gnu.org">&lt;gnu@gnu.org&gt;</a>。也可以通过<a
href="/contact/">其他联系方法</a>联系自由软件基金会(FSF)。有关失效链接或其他错误和建议,请发送邮件到<a
href="mailto:webmasters@gnu.org">&lt;webmasters@gnu.org&gt;</a>。</p>

<p>
<!-- TRANSLATORS: Ignore the original text in this paragraph,
        replace it with the translation of these two:

        We work hard and do our best to provide accurate, good quality
        translations.  However, we are not exempt from imperfection.
        Please send your comments and general suggestions in this regard
        to <a href="mailto:web-translators@gnu.org">

        &lt;web-translators@gnu.org&gt;</a>.</p>

        <p>For information on coordinating and submitting translations of
        our web pages, see <a
        href="/server/standards/README.translations.html">Translations
        README</a>. -->
若您想翻译本文,请参看<a
href="/server/standards/README.translations.html">翻译须知</a>获取有关协调和提交翻译的相关事项。</p>
</div>

<!-- Regarding copyright, in general, standalone pages (as opposed to
     files generated as part of manuals) on the GNU web server should
     be under CC BY-ND 4.0.  Please do NOT change or remove this
     without talking with the webmasters or licensing team first.
     Please make sure the copyright date is consistent with the
     document.  For web pages, it is ok to list just the latest year the
     document was modified, or published.
     
     If you wish to list earlier years, that is ok too.
     Either "2001, 2002, 2003" or "2001-2003" are ok for specifying
     years, as long as each year in the range is in fact a copyrightable
     year, i.e., a year in which the document was published (including
     being publicly visible on the web or in a revision control system).
     
     There is more detail about copyright years in the GNU Maintainers
     Information document, www.gnu.org/prep/maintain. -->
<p>Copyright &copy; 2009-2013, 2016, 2017, 2018, 2019 Richard Stallman</p>

<p>本页面使用<a rel="license"
href="http://creativecommons.org/licenses/by-nd/4.0/">Creative Commons
Attribution-NoDerivatives 4.0 International License</a>授权。</p>

<!--#include virtual="/server/bottom-notes.zh-cn.html" -->
<div class="translators-credits">

<!--TRANSLATORS: Use space (SPC) as msgstr if you don't want credits.-->
<b>翻译团队</b>:<a rel="team"
href="https://savannah.gnu.org/projects/www-zh-cn/">&lt;CTT&gt;</a>,2017-2019。</div>

<p class="unprintable"><!-- timestamp start -->
最后更新:

$Date: 2019/12/30 12:08:30 $

<!-- timestamp end -->
</p>
</div>
</div>
<!-- for class="inner", starts in the banner include -->
</body>
</html>