open pdf and draw c# : Add hyperlinks to pdf control Library system azure asp.net wpf console %5BO%60Reilly%5D%20-%20JavaScript.%20The%20Definitive%20Guide,%206th%20ed.%20-%20%5BFlanagan%5D70-part1604

main thread, and without blocking the computations being concurrently performed in
other workers.
Worker Execution Model
Worker threads run their code (and all imported scripts) synchronously from top to
bottom, and then enter an asynchronous phase in which they respond to events and
timers. If a worker registers an 
onmessage
event handler, it will never exit as long as
there is a possibility that message events will still arrive. But if a worker doesn’t listen
for messages, it will run until there are no further pending tasks (such as download and
timers) and all task-related callbacks have been called. Once all registered callbacks
have been called, there is no way a worker can begin a new task, so it is safe for the
thread to exit. Imagine a worker with no 
onmessage
event handler that downloads a file
using XMLHttpRequest. If the 
onload
handler for that download begins a new down-
load or registers a timeout with 
setTimeout()
, the thread has new tasks and keeps run-
ning. Otherwise, the thread exits.
Since WorkerGlobalScope is the global object for workers, it has all of the properties
of the core JavaScript global object, such as the 
JSON
object, the 
isNaN()
function, and
the 
Date()
constructor. (Look up 
Global
in the core language reference section for a
complete list.) In addition, however, WorkerGlobalScope also has the following prop-
erties of the client-side Window object:
self
is a reference to the global object itself. Note, however, that WorkerGlobal-
Scope does not have the synonymous 
window
property that Window objects have.
• The  timer  methods 
setTimeout()
clearTimeout()
setInterval()
and
clearInterval()
.
• A 
location
property that describes the URL that was passed to the 
Worker()
con-
structor. This property refers to a Location object, just as the 
location
property of
a Window does. The Location object has properties 
href
protocol
host
host
name
port
pathname
search
, and 
hash
. In a worker, these properties are read-only.
• A 
navigator
property that refers to an object with properties like those of the Nav-
igator object of a window. A worker’s navigator object has properties 
appName
,
appVersion
platform
userAgent
, and 
onLine
.
• The usual event target methods 
addEventListener()
and 
removeEventListener()
.
• An 
onerror
property that you can set to an error handler function like the
Window.onerror
handler described in §14.6. An error handler, if you register one,
is passed the error message, URL, and line number as three string arguments. It
can return 
false
to indicate that the error has been handled and should not be
propagated as an error event on the Worker object. (At the time of this writing,
however, error handling within a worker is not implemented interoperably across
browsers.)
Finally, the WorkerGlobalScope object includes important client-side JavaScript con-
structor objects. These include 
XMLHttpRequest()
so that workers can perform scripted
22.4  Web Workers | 683
Client-Side
JavaScript
Add hyperlinks to pdf - insert, remove PDF links in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Free C# example code is offered for users to edit PDF document hyperlink (url), like inserting and deleting
adding an email link to a pdf; clickable links in pdf from word
Add hyperlinks to pdf - VB.NET PDF url edit library: insert, remove PDF links in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Help to Insert a Hyperlink to Specified PDF Document Page
c# read pdf from url; add hyperlink in pdf
HTTP (see Chapter 18) and the 
Worker()
constructor so that workers can create their
own worker threads. (At the time of this writing, the 
Worker()
constructor is not avail-
able to workers in Chrome and Safari, however.)
A number of the HTML5 APIs described later in this chapter define features that are
available through both an ordinary Window object and also in workers through the
WorkerGlobalScope. Often, the Window object will define an asynchronous API and
the WorkerGlobalScope will add a synchronous version of the same basic API. These
“worker-enabled” APIs will be described when we come to them later in the chapter.
Advanced Worker Features
The worker threads described in this section are dedicated workers: they are associated
with, or dedicated to, a single parent thread. The Web Workers specification defines
another type of worker, the shared worker. As I write this, browsers do not yet imple-
ment shared workers. The intent, however, is that a shared worker is a kind of named
resource that can provide a computational service to any thread that cares to connect
to it. In practice, interacting with a shared worker is like communicating with a server
over a network socket.
The “socket” for a shared worker is known as a MessagePort. MessagePorts define a
message-passing API like we’ve seen for dedicated workers and cross-document mes-
saging: they have a 
postMessage()
method and an 
onmessage
event handler attribute.
HTML5 allows you to create connected pairs of MessagePort objects with the 
Message
Channel()
constructor. You can pass MessagePorts (via a special 
postMessage()
argu-
ment) to other windows or other workers and use them as dedicated communication
channels. MessagePorts and MessageChannels are an advanced API that is not yet sup-
ported by many browsers and is not covered here.
22.4.3  Web Worker Examples
We’ll end this section with two Web Worker examples. The first demonstrates how to
perform long computations in a worker thread so that they don’t affect the UI respon-
siveness of the main thread. The second example demonstrates how worker threads
can use simpler synchronous APIs.
Example 22-6 defines a 
smear()
function that expects an 
<img>
element as its argument.
It applies a motion blur effect to “smear” the image to the right. It uses techniques from
Chapter 21 to copy the image to an offscreen 
<canvas>
element and then to extract the
image’s pixels to an ImageData object. You cannot pass an 
<img>
or a 
<canvas>
element
to a worker via 
postMessage()
, but you can pass an ImageData object (details are in
“Structured Clones” on page 672). Example 22-6 creates a Worker object and calls
postMessage()
to send it the pixels to be smeared. When the worker sends the processed
pixels back, the code copies them back into the 
<canvas>
, extracts them as a 
data://
URL, and sets that URL on the 
src
property of the original 
<img>
element.
684 | Chapter 22: HTML5 APIs
Download from Wow! eBook <www.wowebook.com>
C# PDF Convert to HTML SDK: Convert PDF to html files in C#.net
Embed PDF hyperlinks to HTML links. How to Use C#.NET Demo Code to Convert PDF Document to HTML5 Files in C#.NET Class. Add necessary references:
adding hyperlinks to pdf; add links to pdf online
VB.NET PDF Convert to HTML SDK: Convert PDF to html files in vb.
Turn PDF images to HTML images in VB.NET. Embed PDF hyperlinks to HTML links in VB.NET. Convert PDF to HTML in VB.NET Demo Code. Add necessary references:
check links in pdf; add hyperlink to pdf acrobat
Example 22-6. Creating a Web Worker for image processing
// Asynchronously replace the contents of the image with a smeared version.
// Use it like this: <img src="testimage.jpg" onclick="smear(this)"/>
function smear(img) {
// Create an offscreen <canvas> the same size as the image
var canvas = document.createElement("canvas");
canvas.width = img.width; 
canvas.height = img.height;
// Copy the image into the canvas, then extract its pixels
var context = canvas.getContext("2d"); 
context.drawImage(img, 0, 0);          
var pixels = context.getImageData(0,0,img.width,img.height)
// Send the pixels to a worker thread
var worker = new Worker("SmearWorker.js");      // Create worker
worker.postMessage(pixels);                     // Copy and send pixels
// Register a handler to get the worker's response
worker.onmessage = function(e) {
var smeared_pixels = e.data;                // Pixels from worker
context.putImageData(smeared_pixels, 0, 0); // Copy them to the canvas
img.src = canvas.toDataURL();               // And then to the img
worker.terminate();                         // Stop the worker thread
canvas.width = canvas.height = 0;           // Don't keep pixels around
}
}
Example 22-7 is the code used by the worker thread created in Example 22-6. The bulk
of this example is the image processing function: a modified version of the code from
Example 21-10. Note that this example sets up its message-passing infrastructure in a
single line of code: the 
onmessage
event handler simply smears the image it is passed
and posts it right back.
Example 22-7. Image processing in a Web Worker
// Get an ImageData object from the main thread, process it, send it back
onmessage = function(e) { postMessage(smear(e.data)); }
// Smear the ImageData pixels to the right, producing a motion blur.
// For large images, this function does a lot of computation and would
// cause UI responsiveness issues if it was used on the main thread.
function smear(pixels) {
var data = pixels.data, width = pixels.width, height = pixels.height;
var n = 10, m = n-1;  // Make n bigger for more smearing
for(var row = 0; row < height; row++) {            // For each row
var i = row*width*4 + 4;                       // 2nd pixel offset
for(var col = 1; col < width; col++, i += 4) { // For each column
data[i] =   (data[i] + data[i-4]*m)/n;     // Red pixel component
data[i+1] = (data[i+1] + data[i-3]*m)/n;   // Green
data[i+2] = (data[i+2] + data[i-2]*m)/n;   // Blue
data[i+3] = (data[i+3] + data[i-1]*m)/n;   // Alpha component
}
}
22.4  Web Workers | 685
Client-Side
JavaScript
VB.NET PDF Page Replace Library: replace PDF pages in C#.net, ASP.
all PDF page contents in VB.NET, including text, image, hyperlinks, etc. Replace a Page (in a PDFDocument Object) by a PDF Page Object. Add necessary references:
add link to pdf file; add a link to a pdf in preview
VB.NET PDF Thumbnail Create SDK: Draw thumbnail images for PDF in
PDF document is an easy work and gives quick access to PDF page and file, or even hyperlinks. How to VB.NET: Create Thumbnail for PDF. Add necessary references:
pdf hyperlinks; add hyperlink to pdf in
return pixels;
}
Note that the code in Example 22-7 can process any number of images that are sent to
it. For simplicity, however, Example 22-6 creates a new Worker object for each image
it processes. To ensure that the worker does not just sit around waiting for messages,
it kills the thread with 
terminate()
when done.
Debugging Workers
One of the APIs not available (at least as I write this) in WorkerGlobalScope is the
console API and its invaluable 
console.log()
function. Worker threads can’t log output
and can’t interact with the document at all, so they can be tricky to debug. If a worker
throws an error, the main thread will receive an error event on the Worker object. But
often, you need a way for a worker to output debugging messages that are visible in the
browser’s web console. One straightforward way to do this is to modify the message
passing protocol you use with the worker so that the worker can send debugging mes-
sages somehow. In Example 22-6, for example, we could insert the following code at
the start of the 
onmessage
event handler:
if (typeof e.data === "string") {
console.log("Worker: " + e.data);
return;
}
With that additional code in place, the Worker thread could display debugging mes-
sages simply by passing strings to 
postMessage()
.
The next example demonstrates how Web Workers allow you to write synchronous
code and use it safely in client-side JavaScript. §18.1.2.1 showed how to make syn-
chronous HTTP requests with XMLHttpRequest, but it warned that doing so on the
main browser thread was a very bad practice. In a worker thread, however, it is perfectly
reasonable to make synchronous requests, and Example 22-8 demonstrates worker
code that does just that. Its 
onmessage
event handler expects an array of URLs to be
fetched. It uses the synchronous XMLHttpRequest API to fetch them, and then posts
the textual content of the URLs as an array of strings back to the main thread. Or, if
any of the HTTP requests fail, it throws an error that propagates to the 
onerror
handler
of the Worker.
Example 22-8. Making synchronous XMLHttpRequests in a Web Worker
// This file will be loaded with new Worker(), so it runs as an independent
// thread and can safely use the synchronous XMLHttpRequest API.
// Messages are expected to be arrays of URLs. Synchronously fetch the
// contents of each URL as a string and send back an array of those strings.
onmessage = function(e) {
var urls = e.data;   // Our input: the URLs to fetch
var contents = [];   // Our output: the contents of those URLs
for(var i = 0; i < urls.length; i++) { 
686 | Chapter 22: HTML5 APIs
.NET PDF SDK | Read & Processing PDF files
by this .NET Imaging PDF Reader Add-on. Include extraction of text, hyperlinks, bookmarks and metadata; Annotate and redact in PDF documents; Fully support all
add links to pdf; add hyperlink to pdf
PDF Image Viewer| What is PDF
advanced capabilities, such as text extraction, hyperlinks, bookmarks and Note: PDF processing and conversion is excluded in NET Imaging SDK, you may add it on
add hyperlink to pdf in preview; add links to pdf file
var url = urls[i];                 // For each URL
var xhr = new XMLHttpRequest();    // Begin an HTTP request 
xhr.open("GET", url, false);       // false makes this synchronous
xhr.send();                        // Blocks until response is complete
if (xhr.status !== 200)            // Throw an error if request failed
throw Error(xhr.status + " " + xhr.statusText + ": " + url);
contents.push(xhr.responseText);   // Otherwise, store the URL contents
}
// Finally, send the array of URL contents back to the main thread
postMessage(contents);
}
22.5  Typed Arrays and ArrayBuffers
As you know from Chapter 7, JavaScript arrays are general-purpose objects with nu-
meric properties and a special 
length
property. Array elements can be any JavaScript
value. Arrays can grow or shrink dynamically and can be sparse. JavaScript implemen-
tations perform lots of optimizations so that typical uses of JavaScript arrays are very
fast. Typed arrays are array-like objects (§7.11) that differ from regular arrays in some
important ways:
• The elements of a typed array are all numbers. The constructor used to create the
typed array determines the type (signed or unsigned integers or floating point) and
size (in bits) of the numbers.
• Typed arrays have a fixed length.
• The elements of a typed array are always initialized to 0 when the array is created.
There are eight kinds of typed arrays, each with a different element type. You can create
them with the following constructors:
Constructor
Numeric type
Int8Array()
signed bytes
Uint8Array()
unsigned bytes
Int16Array()
signed 16-bit short integers
Uint16Array()
unsigned 16-bit short integers
Int32Array()
signed 32-bit integers
Uint32Array()
unsigned 32-bit integers
Float32Array()
32-bit floating-point value
Float64Array()
64-bit floating-point value: a regular JavaScript number
22.5  Typed Arrays and ArrayBuffers | 687
Client-Side
JavaScript
Typed Arrays, <canvas>, and Core JavaScript
Typed arrays are an essential part of the WebGL 3D graphics API for the 
<canvas>
element, and browsers have implemented them as part of WebGL. WebGL is not cov-
ered in this book, but typed arrays are generally useful and are covered here. You may
recall from Chapter 21 that the Canvas API defines a 
getImageData()
method that re-
turns an ImageData object. The 
data
property of an ImageData is an array of bytes. The
HTML standard calls this a CanvasPixelArray, but it is essentially the same as the
Uint8Array described here, except for the way it handles values outside of the range 0
to 255.
Note that these types are not part of the core language. A future version of the JavaScript
language is likely to include support for typed arrays like these, but at the time of this
writing, it is unclear whether the language will adopt the API described here or will
create a new API.
When you create a typed array, you pass the array size to the constructor or pass an
array or typed array to initialize the array elements with. Once you have created a typed
array, you can read and write its elements with regular square-bracket notation, just as
you would with any other array-like object:
var bytes = new Uint8Array(1024);       // One kilobyte of bytes
for(var i = 0; i < bytes.length; i++)   // For each element of the array
bytes[i] = i & 0xFF;                // Set it to the low 8 bits of index
var copy = new Uint8Array(bytes);       // Make a copy of the array
var ints = new Int32Array([0,1,2,3]);   // A typed array holding these 4 ints
Modern JavaScript implementations optimize arrays to make them very efficient. Nev-
ertheless, typed arrays can be even more efficient in both execution time and memory
use. The following function computes the largest prime number less than the value you
specify. It uses the Sieve of Eratosthenes algorithm, which requires a large array to keep
track of which numbers are prime and which are composite. Since only a single bit of
information is required for each array element, an Int8Array can be used more effi-
ciently than a regular JavaScript array:
// Return the largest prime smaller than n, using the sieve of Eratosthenes
function sieve(n) {
var a = new Int8Array(n+1);          // a[x] will be 1 if x is composite
var max = Math.floor(Math.sqrt(n));  // Don't do factors higher than this
var p = 2;                           // 2 is the first prime
while(p <= max) {                    // For primes less than max
for(var i = 2*p; i <= n; i += p) // Mark multiples of p as composite
a[i] = 1; 
while(a[++p]) /* empty */;       // The next unmarked index is prime
}
while(a[n]) n--;                     // Loop backward to find the last prime
return n;                            // And return it
}
The 
sieve()
function continues to work if you replace the 
Int8Array()
constructor with
the traditional 
Array()
constructor, but it runs two to three times more slowly and
688 | Chapter 22: HTML5 APIs
requires substantially more memory for large values of the parameter 
n
. You might also
find typed arrays useful when working with numbers for graphics or mathematics:
var matrix = new Float64Array(9);   // A 3x3 matrix
var 3dPoint = new Int16Array(3);    // A point in 3D space
var rgba = new Uint8Array(4);       // A 4-byte RGBA pixel value
var sudoku = new Uint8Array(81);    // A 9x9 sudoku board
JavaScript square-bracket notation allows you to get and set individual elements of a
typed array. But typed arrays also define methods for setting and querying entire regions
of the array. The 
set()
method copies the elements of regular or typed arrays into a
typed array:
var bytes = new Uint8Array(1024)         // A 1K buffer
var pattern = new Uint8Array([0,1,2,3]); // An array of 4 bytes
bytes.set(pattern);      // Copy them to the start of another byte array
bytes.set(pattern, 4);   // Copy them again at a different offset
bytes.set([0,1,2,3], 8); // Or just copy values direct from a regular array
Typed arrays also have a 
subarray
method that returns a portion of the array on which
it is called:
var ints = new Int16Array([0,1,2,3,4,5,6,7,8,9]);       // 10 short integers
var last3 = ints.subaarray(ints.length-3, ints.length); // Last 3 of them
last3[0]       // => 7: this is the same as ints[7]
Note that 
subarray()
does not make a copy of the data. It just returns a new view of
the same underlying values:
ints[9] = -1;  // Change a value in the original array and...
last3[2]       // => -1: it also changes in the subarray
The fact that the 
subarray()
method returns a new view of an existing array reveals
something important about typed arrays: they are all views on an underlying chunk of
bytes known as an ArrayBuffer. Every typed array has three properties that relate to the
underlying buffer:
last3.buffer                // => returns an ArrayBuffer object
last3.buffer == ints.buffer // => true: both are views of the same buffer
last3.byteOffset            // => 14: this view starts at byte 14 of the buffer
last3.byteLength            // => 6: this view is 6 bytes (3 16-bit ints) long
The ArrayBuffer object itself has only a single property that returns its length:
last3.byteLength        // => 6: this view is 6 bytes long
last3.buffer.byteLength // => 20: but the underlying buffer has 20 bytes
ArrayBuffers are just opaque chunks of bytes. You can access those bytes with typed
arrays, but an ArrayBuffer is not itself a typed array. Be careful, however: you can use
numeric array indexing with ArrayBuffers just as you can with any JavaScript object.
Doing so does not give you access to the bytes in the buffer, however:
var bytes = new Uint8Array(8); // Allocate 8 bytes
bytes[0] = 1;                  // Set the first byte to 1
bytes.buffer[0]                // => undefined: buffer doesn't have index 0
bytes.buffer[1] = 255;         // Try incorrectly to set a byte in the buffer
22.5  Typed Arrays and ArrayBuffers | 689
Client-Side
JavaScript
bytes.buffer[1]                // => 255: this just sets a regular JS property
bytes[1]                       // => 0: the line above did not set the byte
You can create ArrayBuffers directly with the 
ArrayBuffer()
constructor, and, given an
ArrayBuffer object, you can create any number of typed array views of that buffer:
var buf = new ArrayBuffer(1024*1024);       // One megabyte
var asbytes = new Uint8Array(buf);          // Viewed as bytes
var asints = new Int32Array(buf);           // Viewed as 32-bit signed integer
var lastK = new Uint8Array(buf,1023*1024);  // Last kilobyte as bytes
var ints2 = new Int32Array(buf, 1024, 256); // 2nd kilobyte as 256 integers
Typed arrays allow you to view the same sequence of bytes in chunks of 8, 16, 32, or
64 bits. This exposes the “endianness”: the order in which bytes are arranged into longer
words. For efficiency, typed arrays use the native endianness of the underlying hard-
ware. On little-endian systems, the bytes of a number are arranged in an ArrayBuffer
from least significant to most significant. On big-endian platforms, the bytes are ar-
ranged from most significant to least significant. You can determine the endianness of
the underlying platform with code like this:
// If the integer 0x00000001 is arranged in memory as 01 00 00 00, then
// we're on a little endian platform. On a big-endian platform we'd get
// get bytes 00 00 00 01 instead.
var little_endian = new Int8Array(new Int32Array([1]).buffer)[0] === 1;
Today, the most common CPU architectures are little-endian. Many network proto-
cols, however, and some binary file formats, require big-endian byte ordering. In
§22.6, you’ll learn how you can use ArrayBuffers to hold bytes read from files or down-
loaded from the network. When you do this, you can’t just assume that the platform
endianness matches the byte order of the data. In general, when working with external
data, you can use Int8Array and Uint8Array to view the data as an array of individual
bytes, but you should not use the other typed arrays with multibyte word sizes. Instead,
you can use the DataView class, which defines methods for reading and writing values
from an ArrayBuffer with explicitly specified byte ordering:
var data;                     // Assume this is an ArrayBuffer from the network
var view = DataView(data);    // Create a view of it
var int = view.getInt32(0);   // Big-endian 32-bit signed int from byte 0
int = view.getInt32(4,false); // Next 32-bit int is also big-endian
int = view.getInt32(8,true)   // Next 4 bytes as a little-endian signed int
view.setInt32(8,int,false);   // Write it back in big-endian format
DataView defines eight 
get
methods for each of the eight typed array formats. They
have names like 
getInt16()
getUint32()
, and 
getFloat64()
. The first argument is the
byte offset within the ArrayBuffer at which the value begins. All of these getter methods,
other than 
getInt8()
and 
getUint8()
, accept an optional boolean value as their second
argument. If the second argument is omitted or is false, big-endian byte ordering is
used. If the second argument is 
true
, little-endian ordering is used.
DataView defines eight corresponding 
set
methods that write values into the under-
lying ArrayBuffer. The first argument is the offset at which the value begins. The second
argument is the value to write. Each of the methods, except 
setInt8()
and
690 | Chapter 22: HTML5 APIs
setUint8()
, accepts an optional third argument. If the argument is omitted or is
false
, the value is written in big-endian format with most significant byte first. If the
argument is 
true
, the value is written in little-endian format with the least significant
byte first.
22.6  Blobs
A Blob is an opaque reference to, or handle for, a chunk of data. The name comes from
SQL databases, where it means “Binary Large Object.” In JavaScript, Blobs often rep-
resent binary data, and they can be large, but neither is required: a Blob could also
represent the contents of a small text file. Blobs are opaque: all you can do with them
directly is determine their size in bytes, ask for their MIME type, and chop them up
into smaller Blobs:
var blob = ...   // We'll see how to obtain a Blob later
blob.size        // Size of the Blob in bytes
blob.type        // MIME type of the Blob, or "" if unknown
var subblob = blob.slice(0,1024, "text/plain"); // First 1K of the Blob as text
var last = blob.slice(blob.size-1024, 1024);    // Last 1K of the Blob, untyped
The web browser can store Blobs in memory or on disk, and Blobs can represent really
enormous chunks of data (such as video files) that are too large to fit in main memory
without first being broken into smaller pieces with 
slice()
. Because Blobs can be so
large and may require disk access, the APIs that work with them are asynchronous (with
synchronous versions available for use by worker threads).
Blobs are not terribly interesting by themselves, but they serve as a critical data inter-
change mechanism for various JavaScript APIs that work with binary data. Fig-
ure 22-2 illustrates how Blobs can be read from and written to the Web, the local
filesystem, local databases, and also other windows and workers. It also shows how
Blob content can be accessed as text, as typed arrays, or as URLs.
Before you can work with a Blob, you must obtain one somehow. There are a number
of ways to do this, some involving APIs we’ve already covered and some involving APIs
that are described later in this chapter:
• Blobs  are  supported  by  the  structured  clone  algorithm  (see “Structured
Clones” on page 672), which means that you can obtain one from another window
or thread via the message event. See §22.3 and §22.4.
• Blobs can be retrieved from client-side databases, as described in §22.8.
• Blobs can be downloaded from the web via scripted HTTP, using cutting-edge
features of the XHR2 specification. This is covered in §22.6.2.
• You can create your own blobs, using a BlobBuilder object to build them out of
strings, ArrayBuffer objects (§22.5), and other Blobs. The BlobBuilder object is
demonstrated in §22.6.3.
22.6  Blobs | 691
Client-Side
JavaScript
• Finally, and most importantly, the client-side JavaScript File object is a subtype of
Blob: a File is just a Blob of data with a name and a modification date. You can
obtain File objects from 
<input type="file">
elements and from the drag-and-drop
API, as explained in §22.6.1. File objects can also be obtained using the Filesystem
API, which is covered in §22.7.
Once you have a Blob, there are various things you can do with it, many of them sym-
metrical to the items above:
• You can send a Blob to another window or worker thread with 
postMessage()
. See
§22.3 and §22.4.
• You can store a Blob in a client-side database. See §22.8.
• You can upload a Blob to a server by passing it to the 
send()
method of an
XMLHttpRequest object. The file upload example (Example 18-9) demonstrated
how to do this (remember, a File object is just a specialized kind of Blob).
Figure 22-2. Blobs and the APIs that use them
692 | Chapter 22: HTML5 APIs
Documents you may be interested
Documents you may be interested