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

前端 未结 4 896
北恋
北恋 2020-12-31 18:23

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

The problem

相关标签:
4条回答
  • 2020-12-31 18:49

    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.

    0 讨论(0)
  • 2020-12-31 19:02

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

    0 讨论(0)
  • 2020-12-31 19:08

    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" />
    
    0 讨论(0)
  • 2020-12-31 19:12

    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

    0 讨论(0)
提交回复
热议问题