HTML provides a crossorigin attribute for images that, in combination with an appropriate CORS header, allows images defined by the <img> element that are loaded from foreign origins to be used in a <canvas> as if they had been loaded from the current origin.

CORS 设置属性 for details on how the crossorigin attribute is used.

Security and tainted canvases

Because the pixels in a canvas's bitmap can come from a variety of sources, including images or videos retrieved from other hosts, it's inevitable that security problems may arise.

As soon as you draw into a canvas any data that was loaded from another origin without CORS approval, the canvas becomes tainted . A tainted canvas is one which is no longer considered secure, and any attempts to retrieve image data back from the canvas will cause an exception to be thrown.

If the source of the foreign content is an HTML <img> or SVG <svg> element, attempting to retrieve the contents of the canvas isn't allowed.

If the foreign content comes from an image obtained from either as HTMLCanvasElement or ImageBitMap , and the image source doesn't meet the same origin rules, attempts to read the canvas's contents are blocked.

Calling any of the following on a tainted canvas will result in an error:

Attempting any of these when the canvas is tainted will cause a SecurityError to be thrown. This protects users from having private data exposed by using images to pull information from remote web sites without permission.

Storing an image from a foreign origin

In this example, we wish to permit images from a foreign origin to be retrieved and saved to local storage. Implementing this requires configuring the server as well as writing code for the web site itself.

Web server configuration

The first thing we need is a server that's configured to host images with the Access-Control-Allow-Origin header configured to permit cross-origin access to image files.

Let's assume we're serving our site using Apache . Consider the HTML5 Boilerplate Apache server configuration file for CORS images , shown below:

<IfModule mod_setenvif.c>
  <IfModule mod_headers.c>
    <FilesMatch "\.(bmp|cur|gif|ico|jpe?g|png|svgz?|webp|avifs?)$">
      SetEnvIf Origin ":" IS_CORS
      Header set Access-Control-Allow-Origin "*" env=IS_CORS
    </FilesMatch>
  </IfModule>
</IfModule>
		

In short, this configures the server to allow graphic files (those with the extensions ".bmp", ".cur", ".gif", ".ico", ".jpg", ".jpeg", ".png", ".svg", ".svgz", and ".webp") to be accessed cross-origin from anywhere on the internet.

Implementing the save feature

Now that the server has been configured to allow retrieval of the images cross-origin, we can write the code that allows the user to save them to local 本地存储 , just as if they were being served from the same domain the code is running on.

The key is to use the crossorigin attribute by setting crossOrigin HTMLImageElement into which the image will be loaded. This tells the browser to request cross-origin access when trying to download the image data.

Starting the download

The code that starts the download (say, when the user clicks a "Download" button), looks like this:

function startDownload() {
  let imageURL = "https://cdn.glitch.com/4c9ebeb9-8b9a-4adc-ad0a-238d9ae00bb5%2Fmdn_logo-only_color.svg?1535749917189";
  downloadedImg = new Image;
  downloadedImg.crossOrigin = "Anonymous";
  downloadedImg.addEventListener("load", imageReceived, false);
  downloadedImg.src = imageURL;
}
		

We're using a hard-coded URL here ( imageURL ), but that could easily come from anywhere. To begin downloading the image, we create a new HTMLImageElement object by using the Image() constructor. The image is then configured to allow cross-origin downloading by setting its crossOrigin 属性到 "Anonymous" (that is, allow non-authenticated downloading of the image cross-origin). An event listener is added for the load event being fired on the image element, which means the image data has been received.

Finally, the image's src attribute is set to the URL of the image to download; this triggers the download to begin.

Receiving and saving the image

The code that handles the newly-downloaded image is found in the imageReceived() 方法:

function imageReceived() {
  let canvas = document.createElement("canvas");
  let context = canvas.getContext("2d");
  canvas.width = downloadedImg.width;
  canvas.height = downloadedImg.height;
  context.drawImage(downloadedImg, 0, 0);
  imageBox.appendChild(canvas);
  try {
    localStorage.setItem("saved-image-example", canvas.toDataURL("image/png"));
  }
  catch(err) {
    console.log("Error: " + err);
  }
}
		

imageReceived() is called to handle the "load" event on the HTMLImageElement that receives the downloaded image. This event is triggered once the downloaded data is all available. It begins by creating a new <canvas> element that we'll use to convert the image into a data URL, and by getting access to the canvas's 2D drawing context ( CanvasRenderingContext2D ) in the variable context .

The canvas's size is adjusted to match the received image, then the image is drawn into the canvas using drawImage() . The canvas is then inserted into the document so the image is visible.

Now it's time to actually save the image locally. To do this, we use the Web Storage API's local storage mechanism, which is accessed through the localStorage global. The canvas method toDataURL() is used to convert the image into a data:// URL representing a PNG image, which is then saved into local storage using setItem() .

You can try out or remix this example on Glitch.

另请参阅

元数据

  • 最后修改:
  1. Allowing cross-origin use of images and canvas
  2. 使用 CSS 将颜色应用到 HTML 元素
  3. Block-level elements
  4. DASH Adaptive Streaming for HTML 5 Video
  5. 用于 HTML 的日期和时间格式
  6. 全局属性
    1. 全局属性
    2. accesskey
    3. autocapitalize
    4. class
    5. contenteditable
    6. contextmenu
    7. data-*
    8. dir
    9. draggable
    10. dropzone
    11. hidden
    12. id
    13. inputmode
    14. is
    15. itemid
    16. itemprop
    17. itemref
    18. itemscope
    19. itemtype
    20. lang
    21. part
    22. slot
    23. spellcheck
    24. style
    25. tabindex
    26. title
    27. translate
    28. x-ms-acceleratorkey
    29. x-ms-format-detection
  7. HTML 属性参考
    1. HTML 属性参考
    2. HTML attribute: accept
    3. HTML attribute: capture
    4. HTML attribute: crossorigin
    5. HTML attribute: max
    6. HTML attribute: maxlength
    7. HTML attribute: min
    8. HTML attribute: minlength
    9. HTML attribute: multiple
    10. HTML attribute: pattern
    11. HTML attribute: readonly
    12. HTML attribute: rel
    13. HTML attribute: required
    14. HTML attribute: size
    15. HTML attribute: step
    16. The HTML autocomplete attribute
    17. 被禁用
  8. HTML documentation index
  9. HTML 元素参考
    1. HTML 元素参考
    2. <a>: The Anchor element
    3. <abbr>: The Abbreviation element
    4. <acronym>
    5. <address>: The Contact Address element
    6. <applet>: The Embed Java Applet element
    7. <area>
    8. <article>: The Article Contents element
    9. <aside>: The Aside element
    10. <audio>: The Embed Audio element
    11. <b>: The Bring Attention To element
    12. <base>: The Document Base URL element
    13. <basefont>
    14. <bdi>: The Bidirectional Isolate element
    15. <bdo>: The Bidirectional Text Override element
    16. <bgsound>: The Background Sound element (obsolete)
    17. <big>: The Bigger Text element
    18. <blink>: The Blinking Text element (obsolete)
    19. <blockquote>: The Block Quotation element
    20. <body>: The Document Body element
    21. <br>: The Line Break element
    22. <button>: The Button element
    23. <canvas>: The Graphics Canvas element
    24. <caption>: The Table Caption element
    25. <center>: The Centered Text element (obsolete)
    26. <cite>: The Citation element
    27. <code>: The Inline Code element
    28. <col>
    29. <colgroup>
    30. <command>: The HTML Command element
    31. <content>: The Shadow DOM Content Placeholder element (obsolete)
    32. <data>
    33. <datalist>: The HTML Data List element
    34. <dd>: The Description Details element
    35. <del>: The Deleted Text element
    36. <details>: The Details disclosure element
    37. <dfn>: The Definition element
    38. <dialog>: The Dialog element
    39. <dir>: The Directory element (obsolete)
    40. <div>: The Content Division element
    41. <dl>: The Description List element
    42. <dt>: The Description Term element
    43. <element>: The Custom Element element (Obsolete)
    44. <em>: The Emphasis element
    45. <embed>: The Embed External Content element
    46. <fieldset>: The Field Set element
    47. <figcaption>: The Figure Caption element
    48. <figure>: The Figure with Optional Caption element
    49. <font>
    50. <footer>
    51. <form>
    52. <frame>
    53. <frameset>
    54. <h1>–<h6>: The HTML Section Heading elements
    55. <head>: The Document Metadata (Header) element
    56. <header>
    57. <hgroup>
    58. <hr>: The Thematic Break (Horizontal Rule) element
    59. <html>: The HTML Document / Root element
    60. <i>: The Idiomatic Text element
    61. <iframe>: The Inline Frame element
    62. <image>: The obsolete Image element
    63. <img>: The Image Embed element
    64. <input>: The Input (Form Input) element
    65. <ins>
    66. <isindex>
    67. <kbd>: The Keyboard Input element
    68. <keygen>
    69. <label>
    70. <legend>
    71. <li>
    72. <link>: The External Resource Link element
    73. <listing>
    74. <main>
    75. <map>
    76. <mark>: The Mark Text element
    77. <marquee>: The Marquee element (Obsolete)
    78. <menu>
    79. <menuitem>
    80. <meta>: The Document-level Metadata element
    81. <meter>: The HTML Meter element
    82. <multicol>: The HTML Multi-Column Layout element (Obsolete)
    83. <nav>: The Navigation Section element
    84. <nextid>: The NeXT ID element (Obsolete)
    85. <nobr>: The Non-Breaking Text element (obsolete)
    86. <noembed>: The Embed Fallback element (Obsolete)
    87. <noframes>: The Frame Fallback element
    88. <noscript>
    89. <object>
    90. <ol>: The Ordered List element
    91. <optgroup>
    92. <option>: The HTML Option element
    93. <output>: The Output element
    94. <p>: The Paragraph element
    95. <param>: The Object Parameter element
    96. <picture>: The Picture element
    97. <plaintext>: The Plain Text element (Deprecated)
    98. <pre>: The Preformatted Text element
    99. <progress>: The Progress Indicator element
    100. <q>: The Inline Quotation element
    101. <rb>: The Ruby Base element
    102. <rp>: The Ruby Fallback Parenthesis element
    103. <rt>: The Ruby Text element
    104. <rtc>: The Ruby Text Container element
    105. <ruby>
    106. <s>
    107. <samp>: The Sample Output element
    108. <script>: The Script element
    109. <section>: The Generic Section element
    110. <select>: The HTML Select element
    111. <shadow>: The obsolete Shadow Root element
    112. <slot>
    113. <small>: the side comment element
    114. <source>: The Media or Image Source element
    115. <spacer>
    116. <span>
    117. <strike>
    118. <strong>: The Strong Importance element
    119. <style>: The Style Information element
    120. <sub>: The Subscript element
    121. <summary>: The Disclosure Summary element
    122. <sup>: The Superscript element
    123. <table>: The Table element
    124. <tbody>: The Table Body element
    125. <td>: The Table Data Cell element
    126. <template>: The Content Template element
    127. <textarea>
    128. <tfoot>: The Table Foot element
    129. <th>
    130. <thead>: The Table Head element
    131. <time>
    132. <title>: The Document Title element
    133. <tr>: The Table Row element
    134. <track>: The Embed Text Track element
    135. <tt>: The Teletype Text element (obsolete)
    136. <u>: The Unarticulated Annotation (Underline) element
    137. <ul>: The Unordered List element
    138. <var>: The Variable element
    139. <video>: The Video Embed element
    140. <wbr>
    141. <xmp>
  10. HTML 参考
  11. 内联元素
  12. Link 类型
    1. Link 类型
    2. Link types: dns-prefetch
    3. Link types: manifest
    4. Link types: modulepreload
    5. Link types: noopener
    6. Link types: noreferrer
    7. Link types: preconnect
    8. Link types: prefetch
    9. Link types: preload
    10. Link types: prerender
  13. Microdata
  14. Microformats
  15. 采用 rel="preload" 预加载内容
  16. Quirks Mode and Standards Mode
  17. Using the application cache

版权所有  © 2014-2026 乐数软件    

工业和信息化部: 粤ICP备14079481号-1