1 | /*!
|
---|
2 | \inmodule QtWebKit
|
---|
3 | \page qtwebkit-bridge.html
|
---|
4 | \title The QtWebKit Bridge
|
---|
5 | \contentspage QtWebKit
|
---|
6 | \section1 Overview
|
---|
7 | \section2 The technology
|
---|
8 |
|
---|
9 | The QtWebKit bridge is a mechanism that extends WebKit's JavaScript environment to access native
|
---|
10 | objects that are represented as \l{QObject}s. It takes advantage of the \l{QObject} introspection,
|
---|
11 | a part of the \l{Object Model}, which makes it easy to integrate with the dynamic JavaScript environment,
|
---|
12 | for example \l{QObject} properties map directly to JavaScript properties.
|
---|
13 |
|
---|
14 | For example, both JavaScript and QObjects have properties: a construct that represent a getter/setter
|
---|
15 | pair under one name.
|
---|
16 |
|
---|
17 | \section2 Use Cases
|
---|
18 |
|
---|
19 | There are two main use cases for the QtWebKit bridge. Web content in a native application, and Thin Clients.
|
---|
20 |
|
---|
21 | \section3 Web Content in a Native Application
|
---|
22 |
|
---|
23 | This is a common use case in classic Qt application, and a design pattern used by several modern
|
---|
24 | applications. For example, an application that contains a media-player, playlist manager, and music store.
|
---|
25 | The playlist manager is usually best authored as a classic desktop application,
|
---|
26 | with the native-looking robust \l{QWidget}s helping with producing that application.
|
---|
27 | The media-player control, which usually looks custom, can be written using the \l{Graphics View framework}
|
---|
28 | or with in a declarative way with \l{QtDeclarative}. The music store, which shows dynamic content
|
---|
29 | from the internet and gets modified rapidly, is best authored in HTML and maintained on the server.
|
---|
30 |
|
---|
31 | With the QtWebKit bridge, that music store component can interact with native parts of the application,
|
---|
32 | for example, if a file needs to be saved to a specific location.
|
---|
33 |
|
---|
34 | \section3 Thin Client
|
---|
35 |
|
---|
36 | Another use case is using Qt as a native backend to a full web application,
|
---|
37 | referred to here as a thin client. In this use-case, the entire UI is driven by
|
---|
38 | HTML, JavaScript and CSS, and native Qt-based components are used to allow that application
|
---|
39 | access to native features not usually exposed to the web, or to enable helper components that
|
---|
40 | are best written with C++.
|
---|
41 |
|
---|
42 | An example for such a client is a UI for a video-on-demand service on a TV. The entire content and
|
---|
43 | UI can be kept on the server, served dynamically through HTTP and rendered with WebKit, with additional
|
---|
44 | native components for accessing hardware-specific features like extracting the list of images
|
---|
45 | out of the video.
|
---|
46 |
|
---|
47 | \section2 Difference from Other Bridge Technologies
|
---|
48 |
|
---|
49 | Of course QtWebKit is not the only bridge technology out there. NPAPI, for example,
|
---|
50 | is a long-time standard or web-native bridging. Due to Qt's meta-object system, full applications
|
---|
51 | built partially with web-technologies are much easier to develop. NPAPI, however, is more geared
|
---|
52 | towards cross-browser plugins, due to it being an accepted standard.
|
---|
53 |
|
---|
54 | When developing a plugin for a browser, NPAPI is recommended. When developing a full application
|
---|
55 | that utilizes HTML-rendering, the QtWebKit bridge is recommended.
|
---|
56 |
|
---|
57 | \section2 Relationship with QtScript
|
---|
58 |
|
---|
59 | The QtWebKit bridge is similar to \l{QtScript}, especially to some of the features described in the
|
---|
60 | \l{Making Applications Scriptable} page. However, as of Qt 4.7, full QtScript API is not supported for web applications.
|
---|
61 | That is planned as an enhancement for future versions. You might notice that some of the features
|
---|
62 | described here are an exact copy of the ones described in the \l{Making Applications Scriptable} page. That is because
|
---|
63 | the QtWebKit bridge is a subset of that functionality, and this page tries to capture the full
|
---|
64 | capabilities available through the QtWebKit bridge specifically.
|
---|
65 |
|
---|
66 | \section1 Accessing QObjects
|
---|
67 |
|
---|
68 | \section2 Creating the link via QWebFrame
|
---|
69 |
|
---|
70 | By default, no QObjects are accessible through the web environment, for security reasons.
|
---|
71 | To enable web content access for a native QObject, the application must explicitly grant it access,
|
---|
72 | using the following call:
|
---|
73 |
|
---|
74 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 0
|
---|
75 |
|
---|
76 | See \l{QWebFrame::addToJavaScriptWindowObject()} for more information.
|
---|
77 |
|
---|
78 | \section2 Using Signals and Slots
|
---|
79 |
|
---|
80 | The QtWebKit bridge adapts Qt's central \l{Signals and Slots} feature for
|
---|
81 | scripting. There are three principal ways to use signals and slots
|
---|
82 | with the QtWebKit bridge:
|
---|
83 |
|
---|
84 | \list
|
---|
85 | \i \bold{Hybrid C++/script}: C++ application code connects a
|
---|
86 | signal to a script function. For example, the script function can be
|
---|
87 | a function that the user has typed in, or one that you have read from a
|
---|
88 | file. This approach is useful if you have a QObject but don't want
|
---|
89 | to expose the object itself to the scripting environment; you just
|
---|
90 | want a script to be able to define how a signal should be reacted
|
---|
91 | to, and leave it up to the C++ side of your application to establish
|
---|
92 | the connection.
|
---|
93 |
|
---|
94 | \i \bold{Hybrid script/C++}: A script can connect signals and slots
|
---|
95 | to establish connections between pre-defined objects that the
|
---|
96 | application exposes to the scripting environment. In this scenario,
|
---|
97 | the slots themselves are still written in C++, but the definition of
|
---|
98 | the connections is fully dynamic (script-defined).
|
---|
99 |
|
---|
100 | \i \bold{Purely script-defined}: A script can both define signal
|
---|
101 | handler functions (effectively "slots written in JavaScript"),
|
---|
102 | \e{and} set up the connections that utilize those handlers. For
|
---|
103 | example, a script can define a function that will handle the
|
---|
104 | QLineEdit::returnPressed() signal, and then connect that signal to the
|
---|
105 | script function.
|
---|
106 | \endlist
|
---|
107 |
|
---|
108 | Note that QtScript functions such as qScriptConnect are unavilable in the web environment.
|
---|
109 |
|
---|
110 | \section3 Signal to Function Connections
|
---|
111 |
|
---|
112 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 6
|
---|
113 |
|
---|
114 | In this form of connection, the argument to \c{connect()} is the
|
---|
115 | function to connect to the signal.
|
---|
116 |
|
---|
117 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 7
|
---|
118 |
|
---|
119 | The argument can be a JavaScript function, as in the above
|
---|
120 | example, or it can be a QObject slot, as in
|
---|
121 | the following example:
|
---|
122 |
|
---|
123 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 8
|
---|
124 |
|
---|
125 | When the argument is a QObject slot, the argument types of the
|
---|
126 | signal and slot do not necessarily have to be compatible;
|
---|
127 | If necessary, the QtWebKit bridge will, perform conversion of the signal
|
---|
128 | arguments to match the argument types of the slot.
|
---|
129 |
|
---|
130 | To disconnect from a signal, you invoke the signal's
|
---|
131 | \c{disconnect()} function, passing the function to disconnect
|
---|
132 | as argument:
|
---|
133 |
|
---|
134 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 9
|
---|
135 |
|
---|
136 | When a script function is invoked in response to a signal, the
|
---|
137 | \c this object will be the Global Object.
|
---|
138 |
|
---|
139 | \section3 Signal to Member Function Connections
|
---|
140 |
|
---|
141 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 10
|
---|
142 |
|
---|
143 | In this form of the \c{connect()} function, the first argument
|
---|
144 | is the object that will be bound to the variable, \c this, when
|
---|
145 | the function specified using the second argument is invoked.
|
---|
146 |
|
---|
147 | If you have a push button in a form, you typically want to do
|
---|
148 | something involving the form in response to the button's
|
---|
149 | \c{clicked} signal; passing the form as the \c this object
|
---|
150 | makes sense in such a case.
|
---|
151 |
|
---|
152 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 11
|
---|
153 |
|
---|
154 | To disconnect from the signal, pass the same arguments to \c{disconnect()}:
|
---|
155 |
|
---|
156 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 12
|
---|
157 |
|
---|
158 | \section3 Signal to Named Member Function Connections
|
---|
159 |
|
---|
160 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 14
|
---|
161 |
|
---|
162 | This form of the \c{connect()} function requires that the first argument is
|
---|
163 | the object that will be bound to the variable \c{this} when a function is
|
---|
164 | invoked in response to the signal. The second argument specifies the
|
---|
165 | name of a function that is connected to the signal, and this refers to a
|
---|
166 | member function of the object passed as the first argument (thisObject
|
---|
167 | in the above scheme).
|
---|
168 |
|
---|
169 | Note that the function is resolved when the connection is made, not
|
---|
170 | when the signal is emitted.
|
---|
171 |
|
---|
172 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 15
|
---|
173 |
|
---|
174 | To disconnect from the signal, pass the same arguments to \c{disconnect()}:
|
---|
175 |
|
---|
176 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 17
|
---|
177 |
|
---|
178 | \section3 Error Handling
|
---|
179 |
|
---|
180 | When \c{connect()} or \c{disconnect()} succeeds, the function will
|
---|
181 | return \c{undefined}; otherwise, it will throw a script exception.
|
---|
182 | You can obtain an error message from the resulting \c{Error} object.
|
---|
183 | Example:
|
---|
184 |
|
---|
185 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 18
|
---|
186 |
|
---|
187 | \section3 Emitting Signals from Scripts
|
---|
188 |
|
---|
189 | To emit a signal from script code, you simply invoke the signal
|
---|
190 | function, passing the relevant arguments:
|
---|
191 |
|
---|
192 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 19
|
---|
193 |
|
---|
194 | It is currently not possible to define a new signal in a script;
|
---|
195 | i.e., all signals must be defined by C++ classes.
|
---|
196 |
|
---|
197 | \section3 Overloaded Signals and Slots
|
---|
198 |
|
---|
199 | When a signal or slot is overloaded, the QtWebKit bridge will attempt to
|
---|
200 | pick the right overload based on the actual types of the QScriptValue arguments
|
---|
201 | involved in the function invocation. For example, if your class has slots
|
---|
202 | \c{myOverloadedSlot(int)} and \c{myOverloadedSlot(QString)}, the following
|
---|
203 | script code will behave reasonably:
|
---|
204 |
|
---|
205 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 20
|
---|
206 |
|
---|
207 | You can specify a particular overload by using array-style property access
|
---|
208 | with the \l{QMetaObject::normalizedSignature()}{normalized signature} of
|
---|
209 | the C++ function as the property name:
|
---|
210 |
|
---|
211 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 21
|
---|
212 |
|
---|
213 | If the overloads have different number of arguments, the QtWebKit bridge will
|
---|
214 | pick the overload with the argument count that best matches the
|
---|
215 | actual number of arguments passed to the slot.
|
---|
216 |
|
---|
217 | For overloaded signals, JavaScript will throw an error if you try to connect
|
---|
218 | to the signal by name; you have to refer to the signal with the full
|
---|
219 | normalized signature of the particular overload you want to connect to.
|
---|
220 |
|
---|
221 | \section3 Invokable Methods
|
---|
222 |
|
---|
223 | Both slots and signals are invokable from script by default. In addition, it's also
|
---|
224 | possible to define a method that's invokable from script without it being a signal or a slot.
|
---|
225 | This is especially useful for functions with return types, as slots normally do not return anything
|
---|
226 | (it would be meaningless to return values from a slot, as the connected signals don't handle the returned data).
|
---|
227 | To make a non-slot method invokable, simply add the Q_INVOKABLE macro before its definition:
|
---|
228 |
|
---|
229 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 22
|
---|
230 |
|
---|
231 | \section2 Accessing Properties
|
---|
232 |
|
---|
233 | The properties of the QObject are available as properties
|
---|
234 | of the corresponding JavaScript object. When you manipulate
|
---|
235 | a property in script code, the C++ get/set method for that
|
---|
236 | property will automatically be invoked. For example, if your
|
---|
237 | C++ class has a property declared as follows:
|
---|
238 |
|
---|
239 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 23
|
---|
240 |
|
---|
241 | then script code can do things like the following:
|
---|
242 |
|
---|
243 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 24
|
---|
244 |
|
---|
245 | \section2 Accessing Child QObjects
|
---|
246 |
|
---|
247 | Every named child of the QObject (that is, for which
|
---|
248 | QObject::objectName() is not an empty string) is by default available as
|
---|
249 | a property of the JavaScript wrapper object. For example,
|
---|
250 | if you have a QDialog with a child widget whose \c{objectName} property is
|
---|
251 | \c{"okButton"}, you can access this object in script code through
|
---|
252 | the expression
|
---|
253 |
|
---|
254 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 25
|
---|
255 |
|
---|
256 | Since \c{objectName} is itself a Q_PROPERTY, you can manipulate
|
---|
257 | the name in script code to, for example, rename an object:
|
---|
258 |
|
---|
259 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 26
|
---|
260 |
|
---|
261 | \section2 Data types
|
---|
262 |
|
---|
263 | When calling slots, receiving signals or accessing properties, usually some payload is involved.
|
---|
264 | For example, a property "text" might return a \l{QString} parameter.
|
---|
265 | The QtWebKit bridge does the job of converting between a given JavaScript data-type, and the
|
---|
266 | expected or given Qt type. Each Qt type has a coresponding set of rules of how JavaScript treats it.
|
---|
267 |
|
---|
268 | The data type conversions are also applicable for the data returned from non-void invokable methods.
|
---|
269 |
|
---|
270 | \section3 Numbers
|
---|
271 |
|
---|
272 | All Qt numeric data types are converted to or from a JavaScript number. These include int, short, float,
|
---|
273 | double, and the porable Qt types (qreal, qint etc). A special case is \l{QChar};
|
---|
274 | If a slot expects a QChar, the QtWebKit bridge would use the unicode value in case of a number,
|
---|
275 | or the first character in a string.
|
---|
276 |
|
---|
277 | Note that non-standard (typedefed) number types are not automatically converted to
|
---|
278 | or from a JavaScript number - it's advised to use standard number types for signal, slots
|
---|
279 | and properties.
|
---|
280 |
|
---|
281 | When a non-number is passed as an argument to a method or property that expects a number,
|
---|
282 | the appropriate JavaScript conversion function (parseInt / parseFloat) would be used.
|
---|
283 |
|
---|
284 | \section3 Strings
|
---|
285 |
|
---|
286 | When JavaScript accesses methods or properties that expect a \l{QString}, the QtWebKit bridge
|
---|
287 | will automatically convert the value to a string (if it is not already a string), using the
|
---|
288 | built-in JavaScript toString method.
|
---|
289 |
|
---|
290 | When a QString is passed to JavaScript from a signal or a property, The QtWebKit bridge will
|
---|
291 | convert it into a JavaScript string.
|
---|
292 |
|
---|
293 | \section3 Date & Time
|
---|
294 |
|
---|
295 | Both \l{QDate}, \l{QTime} and \l{QDateTime} are automatically translated to or from the JavaScript
|
---|
296 | Date object. If a number were passed as an argument to a method that expects one of the date/time
|
---|
297 | types, the QtWebKit bridge would treat it as a timestamp. If a sting is passed, QtWebKit would
|
---|
298 | try different Qt date parsing functions to find the right one.
|
---|
299 |
|
---|
300 | \section3 Regular Expressions
|
---|
301 |
|
---|
302 | The QtWebKit bridge would automatically convert JavaScript RegEx object to a \l{QRegExp}.
|
---|
303 | If a string is passed to a method expecting a \l{QRegExp}, the string would be converted
|
---|
304 | to that \l{QRegExp}.
|
---|
305 |
|
---|
306 | \section3 Lists
|
---|
307 |
|
---|
308 | The QtWebKit bridge treats several types of lists in a special way: \l{QVariantList}, \l{QStringList},
|
---|
309 | \l{QObjectList} and \l{QList}<int>. When a slot or property expects one of those list types,
|
---|
310 | the QtWebKit bridge would try to convert a JavaScript array into that type, converting each of
|
---|
311 | the array's elements to the single-element type of the list.
|
---|
312 |
|
---|
313 | The most useful type of list is perhaps \l{QVariantList}, which can be converted to from any
|
---|
314 | JavaScript array.
|
---|
315 |
|
---|
316 | \section3 Compound (JSON) objects
|
---|
317 |
|
---|
318 | JavaScript compound objects, also known as JSON objects, are variables that hold a list
|
---|
319 | of key-value pairs, where all the keys are strings and the values can have any type.
|
---|
320 | This translates very well to \l{QVariantMap}, which is nothing more than a \l{QMap} of \l{QString}
|
---|
321 | to \l{QVariant}.
|
---|
322 |
|
---|
323 | The seamless conversion between JSON objects and \l{QVariantMap} allows for a very convenient
|
---|
324 | way of passing arbitrary structured data between C++ and the JavaScript environment. The native \l{QObject} has
|
---|
325 | to make sure that compound values are converted to \l{QVariantMap}s and \l{QVariantList}s, and JavaScript is
|
---|
326 | guaranteed to receive them in a meaningful way.
|
---|
327 |
|
---|
328 | Note that types that are not supported by JSON, such as JavaScript functions and getters/setters,
|
---|
329 | are not converted.
|
---|
330 |
|
---|
331 | \section3 QVariants
|
---|
332 |
|
---|
333 | When a slot or property accepts a \l{QVariant}, the QtWebKit bridge would create a \l{QVariant} that best
|
---|
334 | matches the argument passed by JavaScript. A string, for example, would become a \l{QVariant} holding a \l{QString},
|
---|
335 | a normal JSON object would become a \l{QVariantMap}, and a JavaScript array would become a \l{QVariantList}.
|
---|
336 |
|
---|
337 | Using \l{QVariant}s generously in C++ in that way makes C++ programming feel a bit more like JavaScript programming,
|
---|
338 | as it adds another level of indirection. Passing \l{QVariant}s around like this q is very flexible, as the program can figure out
|
---|
339 | the type of argument in runtime just like JavaScript would do, but it also takes away from the type-safety and robust
|
---|
340 | nature of C++. It's recommended to use \l{QVariant}s only for convenience high-level functions, and to keep most of your
|
---|
341 | \l{QObject}s somewhat type-safe.
|
---|
342 |
|
---|
343 | \section3 QObjects
|
---|
344 |
|
---|
345 | A pointer to a \l{QObject} or a \l{QWidget} can be passed as payload in signals, slots and properties. That object
|
---|
346 | can then be used like an object that's exposed directly; i.e. its slots can be invoked, its signals connected to etc.
|
---|
347 | However, this functionality is fairly limited - the type used has to be \l{QObject}* or \l{QWidget}*. If the type
|
---|
348 | specified is a pointer to a non-\l{QWidget} subclass of \l{QObject}, the QtWebKit bridge would not recognize it to be
|
---|
349 | a \l{QObject}.
|
---|
350 |
|
---|
351 | In general its advised to use care when passing \l{QObject}s as arguments, as those objects don't become owned by
|
---|
352 | the JavaScript engine; That means that the application developer has to be extra careful not to try to access
|
---|
353 | \l{QObject}s that have already been deleted by the native environment.
|
---|
354 |
|
---|
355 | \section3 Pixmaps and Images
|
---|
356 |
|
---|
357 | \since 4.7
|
---|
358 |
|
---|
359 | The QtWebKit bridge handles \l{QPixmap}s and \l{QImage}s in a special way. Since QtWebKit stores \l{QPixmap}s to
|
---|
360 | represent HTML images, \l{QPixmap}s coming from the native environment can be used directly inside WebKit.
|
---|
361 | A \l{QImage} or a \l{QPixmap} coming from the Qt environment would convert to an intermediate JavaScript object,
|
---|
362 | that can be represented like this:
|
---|
363 |
|
---|
364 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 1
|
---|
365 |
|
---|
366 | The JavaScript environment can then use the pixmap it gets from Qt and display it inside the HTML environment,
|
---|
367 | by assigning it to an existing <img /> element using assignToHTMLImageElement. It can also use the toDataURL() function,
|
---|
368 | which allows using the pixmap as the src attribute of an image or as a background-image url. Note that the toDataURL()
|
---|
369 | function is costly and should be used with caution.
|
---|
370 |
|
---|
371 | Example code:
|
---|
372 |
|
---|
373 | C++:
|
---|
374 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 2
|
---|
375 |
|
---|
376 | HTML:
|
---|
377 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 3
|
---|
378 |
|
---|
379 | When a Qt object expects a \l{QImage} or a \l{QPixmap} as input, and the argument passed is an HTML image element,
|
---|
380 | the QtWebKit bridge would convert the pixmap assigned to that image element into a \l{QPixmap} or a \l{QImage}.
|
---|
381 |
|
---|
382 | \since 4.7
|
---|
383 |
|
---|
384 | \section3 QWebElement
|
---|
385 |
|
---|
386 | A signal, slot or property that expects or returns a \l{QWebElement} can work seamlessly with JavaScript references
|
---|
387 | to DOM elements. The JavaScript environment can select DOM elements, keep them in variables, then pass them to Qt as
|
---|
388 | a \l{QWebElement}, and receive them back. Example:
|
---|
389 |
|
---|
390 | C++:
|
---|
391 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 4
|
---|
392 |
|
---|
393 | HTML:
|
---|
394 | \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 5
|
---|
395 |
|
---|
396 | This is specifically useful to create custom renderers or extensions to the web environment. Instead of forcing Qt
|
---|
397 | to select the element, the web environment already selects the element and then send the selected element directly to Qt.
|
---|
398 |
|
---|
399 | Note that \l{QWebElement}s are not thread safe - an object handling them has to live in the UI thread.
|
---|
400 |
|
---|
401 | \section1 Architecture issues
|
---|
402 |
|
---|
403 | \section2 Limiting the Scope of the Hybrid Layer
|
---|
404 |
|
---|
405 | When using QtWebKit's hybrid features, it is a common pitfall to make the API exposed to JavaScript very rich and
|
---|
406 | use all its features. This, however, leads to complexity and can create bugs that are hard to trace.
|
---|
407 | Instead, it is advisable to keep the hybrid layer small and manageable: create a gate only when
|
---|
408 | there's an actual need for it, i.e. there's a new native enabler that requires a direct interface
|
---|
409 | to the application layer. Sometimes new functionality is better handled internally in the native layer
|
---|
410 | or in the web layer; simplicity is your friend.
|
---|
411 |
|
---|
412 | This usually becomes more apparent when the hybrid layer can create or destroy objects, or uses
|
---|
413 | signals slots or properties with a \l{QObject}* argument. It is advised to be very careful and to treat
|
---|
414 | an exposed \l{QObject} as a system - with careful attention to memory management and object ownership.
|
---|
415 |
|
---|
416 | \section2 Internet Security
|
---|
417 |
|
---|
418 | When exposing native object to an open web environment, it is importwhichant to understand the security
|
---|
419 | implications. Think whether the exposed object enables the web environment access to things that
|
---|
420 | shouldn't be open, and whether the web content loaded by that web page comes from a trusted. In general, when
|
---|
421 | exposing native QObjects that give the web environment access to private information or to functionality
|
---|
422 | that's potentially harmful to the client, such exposure should be balanced by limiting the web page's
|
---|
423 | access to trusted URLs only with HTTPS, and by utilizing other measures as part of a security strategy.
|
---|
424 |
|
---|
425 |
|
---|
426 |
|
---|
427 | */
|
---|