Can not make GWT application work as Chrome packaged app, probably due to CSP

妖精的绣舞 提交于 2019-12-30 03:18:27

问题


Keep getting CSP errors: "Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'"

The problem is probably due to HTML files generated by GWT which contain inline JS.

UPD: Changing to manifest version 1 helped, but this is a temporary workaroud, as Chrome 21 complains that it will no longer be supported.

UPD2: <add-linker name="xsiframe" /> does not help either


回答1:


GWT 2.5.1 has finally fixed this problem. The release notes documenting this are here:

https://developers.google.com/web-toolkit/release-notes#Release_Notes_2_5_1

and they state that:

"Apps built with DirectInstallLinker should work in a page where inline scripts are forbidden (e.g. a Chrome extension)"

This means that it is now possible to use DirectInstallLinker to link your Chrome packaged app in a manner that satisfies the new security requirements of manifest version 2 regarding inline scripts. That is, by using DirectInstallLinker to link your app with GWT 2.5.1 selected as your GWT version, GWT will not place any script elements inline in its generated Javascript, and thus the new manifest version 2 requirement that there be no inline scripts will not be violated.

I have found that SingleScriptLinker also seems to work for my own app; however, Issue 7685 warns against using the SingleScriptLinker because "This generates a $doc.write line which is forbidden in packaged apps." I am using DirectInstallLinker myself.

Here is the Javadoc for DirectInstallLinker:

http://google-web-toolkit.googlecode.com/svn/javadoc/2.5/com/google/gwt/core/linker/DirectInstallLinker.html

To use this linker, you can include the following in your *.gwt.xml file:

<define-linker name="dil" class="com.google.gwt.core.linker.DirectInstallLinker"/>
<add-linker name="dil" />

(dil can be replaced by anything you choose, so long as there are no dashes or other illegal characters).

You will need to select GWT 2.5.1 as your version of GWT. If you're using an older version of GWT in an out-of-date version of Eclipse such as Ganymede (as I was), you'll have to upgrade to at least Helios and then import your project to your new Eclipse environment. The archive URLs for the Google Plugin for Eclipse that can be used for the latest three Eclipse versions can be found here:

https://developers.google.com/eclipse/docs/download

With the above in place, you should be able to set

"manifest_version": 2

in your manifest.json file and not experience any errors due to GWT-generated inline Javascript. This should allow your Chrome Web app to be acceptable to the Chrome Web Store (which now requires manifest version 2 for any new apps or for updates to present apps), so long as there are no other issues.




回答2:


EDIT: new GWT bug reported: http://code.google.com/p/google-web-toolkit/issues/detail?id=7685, see also http://gwt-code-reviews.appspot.com/1838803/ which is related to this bug

In other words, it looks like, when fixed, you'll simply have to use the DirectInstallLinker (<add-linker name='direct_install'/>).

In the mean time, IIUC, you'd have to extend DirectInstallLinker and:

  • override getJsInstallLocation to return a copy a installLocaltionIframe.js without the $wnd part
  • override getModulePrefix to prepend var $wnd = $wnd || window.parent; to what's generated by super.getModulePrefix

I don't know CSP enough to give a complete answer, but the xsiframe linker is "customizable": create a class that extends com.google.gwt.core.linker.CrossSiteIframeLinker and overrides the appropriate methods, then use with a <define-linker> and <add-linker> in your *.gwt.xml.

For instance, getJsInstallLocation defaults to com/google/gwt/core/ext/linker/impl/installLocationIframe.js but there's a com/google/gwt/core/ext/linker/impl/installLocationMainWindows.js alternate implementation.

Similarly (and probably more importantly), getJsInstallScript defaults to com/google/gwt/core/ext/linker/impl/installScriptEarlyDownload.js but there's also a com/google/gwt/core/ext/linker/impl/installScriptDirect.js alternate implementation.

See http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java#204, http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/ and http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/core/Core.gwt.xml




回答3:


Thanks to Thomas Broyer's advice. I created this GWT Linker. Now my GWT application runs perfectly as an Chrome Application (Tested on Chrome 32 and GWT 2.5.1).

public class CSPCompatibleLinker extends DirectInstallLinker {

@Override
protected String getJsInstallLocation(LinkerContext context) {
    return "com/google/gwt/core/ext/linker/impl/installLocationMainWindow.js";
} 

}

Dont forget to declare the Linker into your*.gwt.xml file:

<define-linker name="csp" class="com.sfeir.linker.CSPCompatibleLinker"/>
<add-linker name="csp" />



回答4:


Manifest version 2 does not allow inline scripts. You need to make sure all scripts are linked instead and no JavaScript in HTML elements.



来源:https://stackoverflow.com/questions/12123178/can-not-make-gwt-application-work-as-chrome-packaged-app-probably-due-to-csp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!