Packaged Apps and Fonts

1,339 views
Skip to first unread message

Peter Tierney

unread,
Jun 13, 2014, 6:10:01 PM6/13/14
to chromi...@chromium.org
I have created a packaged app that wraps an ExtJs application in the sandbox. I have everything working nicely with the exception of fonts being denied. The docs on this topic are absolutely useless and there seems to be quite a bit of confusion about how to get it to work.

I am seeing 2 errors but the bad one is
Font from origin 'chrome-extension://...' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
and yet nothing else gives these errors. Maybe I'm missing something in my CORS stuff on the server side, but

The CSS files are defined in the ExtJs app and they call fonts in the below fashion
@font-face {
    font-family: 'source_sans_semibold';
    src: url('fonts/SourceSansPro-Semibold.eot');
    src: url('fonts/SourceSansPro-Semibold.eot?#iefix') format('embedded-opentype'),
         url('fonts/SourceSansPro-Semibold.ttf') format('truetype'),
         url('fonts/SourceSansPro-Semibold.svg#pt_sansbold') format('svg');
    font-weight: normal;
    font-style: normal;
}

I've tried putting <all_urls> in permissions on the manifest and other crap I see on posts and nothing works.

Anything useful would be greatly appreciated.

Cheers

LiborB

unread,
Aug 19, 2014, 10:14:23 AM8/19/14
to chromi...@chromium.org
We have exactly the same issue with loading web fonts in our sandboxed chrome packaged application. We filed a related question to blink-dev PSA web facing change: Chrome 37 will reject non-compliant "cross-origin web font requests" discussion.
Anyway, for the time being we used a workaround based on packaging web fonts with the application. We replaced 'src: url(<font file>)' by 'src: url("data:font/opentype;base64,<base64 content of the font file>")' in your @font-face CSS files.


Dne sobota, 14. června 2014 0:10:01 UTC+2 Peter Tierney napsal(a):

Benjamin Kalman

unread,
Aug 19, 2014, 4:22:11 PM8/19/14
to LiborB, Chromium Apps
This doesn't have anything to do with host permissions, it's a CSP issue. Try specifying a font-src in your extension's manifest. See:


--
You received this message because you are subscribed to the Google Groups "Chromium Apps" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-app...@chromium.org.
To post to this group, send email to chromi...@chromium.org.
Visit this group at http://groups.google.com/a/chromium.org/group/chromium-apps/.
For more options, visit https://groups.google.com/a/chromium.org/d/optout.

Peter Tierney

unread,
Aug 19, 2014, 5:48:59 PM8/19/14
to chromi...@chromium.org, libo...@gmail.com
Benjamin:

The links you posted really supply no help at all. I've read those pages and tried all kinds of ways to get this to work and nothing works. If you have a precise example of what you believe to work then please supply that. Maybe even a complete manifest so we can see if perhaps we are missing something you and others believe should be known. The documentation for creating packaged apps/extensions is less than adequate. 

Meggin Kearney

unread,
Aug 19, 2014, 5:59:20 PM8/19/14
to Peter Tierney, Chromium Apps, libo...@gmail.com
Have you read this doc: https://developer.chrome.com/apps/app_external#sandboxing?

It includes a link to a full sandboxing sample.


FYI, the content security policy for extensions is different than the policy for Chrome Apps. Ben provided a link to the extensions CSP policy above. Here's a link to the Chrome Apps policy: https://developer.chrome.com/apps/contentSecurityPolicy

Bummed the docs aren't working for you-- specific feedback would be great!

Meggin


On Tue, Aug 19, 2014 at 2:48 PM, Peter Tierney <schmal...@gmail.com> wrote:
Benjamin:

The links you posted really supply no help at all. I've read those pages and tried all kinds of ways to get this to work and nothing works. If you have a precise example of what you believe to work then please supply that. Maybe even a complete manifest so we can see if perhaps we are missing something you and others believe should be known. The documentation for creating packaged apps/extensions is less than adequate. 

--

Libor Bus

unread,
Aug 20, 2014, 4:30:04 AM8/20/14
to chromi...@chromium.org, schmal...@gmail.com, libo...@gmail.com
My understanding of the problem is that chrome packaged app can not change font-src nor web_accessible_resources (while extensions can). The sandboxed iframe has null origin which is different than origin of the application thus Chrome applies some security rules. 

In the stable Chrome v36 loading web fonts from sandboxed iframe works fine in our packaged app however in Canary Chrome v39 it fails with message:
Font from origin 'chrome-extension://... has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
The security rule for web font changed in Chrome v37, see also discussion in blink-dev group: PSA web facing change: Chrome 37 will reject non-compliant "cross-origin web font requests"

One possible solution is to package web fonts as base64 (see my previous comment). Other possible solution is to send postMessage from the sandboxed iframe to the application window with the web download request. Then the application does the XHR and returns the font as base64 to the sandboxed iframe which dynamically creates @font-face. 

However this approach seems to my to be quite complicated for such simple task as including web font packaged with the application and used from sandboxed html such as:
<link rel="stylesheet" href="font/font-awesome.min.css">
which even works in the current Chrome v36.

Please advise how to use packaged web fonts from the sandbox in Chrome 37 and later so that our applications does not break with the next Chrome release.

Dne úterý, 19. srpna 2014 23:59:20 UTC+2 Meggin Kearney napsal(a):

PhistucK

unread,
Aug 20, 2014, 6:47:02 AM8/20/14
to Libor Bus, Chromium Apps, schmal...@gmail.com

Peter Tierney

unread,
Aug 20, 2014, 10:02:30 AM8/20/14
to chromi...@chromium.org, schmal...@gmail.com, libo...@gmail.com
Libor:

That was my experience as well. Everything was fine and then an update occurred to v39 and all font calls started failing. Who knew that fonts could end up being such a pain. :-/

Also, is there some kind of upgrade notification other than the bars at the top right Chrome? It would be swell if we could see what changes are coming just in the off chance that these upgrades break something in our apps. There's nothing quite like the feeling of a working app suddenly failing or behaving strangely when a unexpected upgrade occurs. It's definitely NOT the best part of waking up.

Benjamin Kalman

unread,
Aug 20, 2014, 10:48:19 AM8/20/14
to Peter Tierney, Chromium Apps, Libor Buš
Ah right, sorry I missed that this was a packaged app, which was the very first thing you said :(

Looking at the documentation on sandboxed pages - https://developer.chrome.com/apps/manifest/sandbox - you should be able to do something like:

{
  ...
  "sandbox": {
    "pages": [...],
    "content_security_policy": "icon-src 'self'"
  }
  ...
}

I'm a little puzzled why this isn't 'self' to begin with to be honest, perhaps it's a bug on our side as fallout from that blink change. I'll chase that up.


--

Benjamin Kalman

unread,
Aug 20, 2014, 10:51:55 AM8/20/14
to Peter Tierney, Chromium Apps, Libor Buš
Oops, font-src not icon-src.

Benjamin Kalman

unread,
Aug 20, 2014, 11:05:26 AM8/20/14
to Peter Tierney, Chromium Apps, Libor Buš
Double-oops - this is a sandboxed so presumably 'self' doesn't really make sense as a CSP directive. You'll need to widen it even further.

Peter Tierney

unread,
Aug 20, 2014, 12:13:08 PM8/20/14
to Benjamin Kalman, Chromium Apps, Libor Buš
Thanks for the info Benjamin. I've tried your suggestion and maybe I'm being too literal, but when I place

"sandbox": {
"pages": ["ui/index.html"],
"content_security_policy": "font-src 'self'"
},

into my manifest.json, Chrome states
Invalid value for 'sandbox.content_security_policy'.

I've tried
"font-src 'none'"
"font-src 'unsafe-inline'"
"font-src 'unsafe-eval'"
and they all produce the same error. These are the only options I see available on sites. Is there another option I'm not finding?

Thanks for the help.
===================================================
Peter Tierney
schmal...@gmail.com

The very wise person, when wishing to elevate people,
Places their position below others.



Benjamin Kalman

unread,
Aug 20, 2014, 12:18:36 PM8/20/14
to Peter Tierney, Chromium Apps, Libor Buš
You would need to put some URL pattern there, but that's hard.

Backing up here, I think you're struggling against the sandboxed page feature and a webview might be more appropriate, as PhistucK mentioned earlier, in fact have a look at that link to an example manifest. It should also be documented along with the webview documentation.

Peter Tierney

unread,
Aug 20, 2014, 6:39:44 PM8/20/14
to Benjamin Kalman, Chromium Apps, Libor Buš
I'm not familiar yet with the webviews but I'll try it out and hopefully it solves the font problem.

Does a webview offer all the functionality of the sandboxed app?

Thanks again.

Benjamin Kalman

unread,
Aug 20, 2014, 7:39:12 PM8/20/14
to Peter Tierney, Chromium Apps, Libor Buš
More or less. You don't use HTML postMessage but instead a method more similar to runtime.sendMessage. That's the main difference I can think of.

Ufuk Cemen

unread,
Sep 4, 2014, 3:04:28 PM9/4/14
to chromi...@chromium.org
Hi Libor,
  I am having this same issue and trying to do your workaround but couldn't get it working. I have a chrome packaged app without Sandbox or Webview; I am adding the @font-face to my css as below :
---------------------------------- 
@font-face {
font-family: 'Icons';
src: url(data:font/ttf;charset=utf-8;base64,<ttf file encoded to base64>) format('truetype'),
url(data:font/woff;charset=utf-8;base64,<woff file encoded to base64>) format('woff'),
url(data:font/svg;charset=utf-8;base64,<svg file encoded to base64>) format('svg');
font-weight: normal;
font-style: normal;
}

[class^="icon-"], [class*=" icon-"] {
font-family: 'Icons';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;

/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.icon-uniF085:before {
content: "\f085";
}

--------------------------
but when I run the application all I see in the chromium is the default square box instead of the icon I am referencing (<span class="icon-uniF085"></span>). I am wondering if anyone got custom or external icons working with the packaged apps. Couldn't find much over the net. Please let me know if there is a workaround in anyway. 

Libor Bus

unread,
Sep 4, 2014, 3:32:03 PM9/4/14
to chromi...@chromium.org
Hello Ufuk,
I attach modified CSS for FontAwesome with font file embedded as base64 in CSS. This workaround which works for me in both Chrome app and its sandbox iframe.
BR,
Libor

Dne čtvrtek, 4. září 2014 21:04:28 UTC+2 Ufuk Cemen napsal(a):
font-awesome.min-base64.zip

Nathan Anderson

unread,
Sep 11, 2014, 9:31:02 AM9/11/14
to chromi...@chromium.org
Hello Libor, 
Could you please explain what you did to get it working?  I have other CSS libraries that suddenly have stopped working.  Thanks!

Nathan Anderson

unread,
Sep 11, 2014, 9:32:09 AM9/11/14
to chromi...@chromium.org
Hello Libor, 
Could you please explain what you did to get it working?  I have other CSS libraries that suddenly have stopped working.  Thanks!

On Thursday, September 4, 2014 2:32:03 PM UTC-5, Libor Bus wrote:

Michael Cole

unread,
Sep 17, 2014, 2:53:36 AM9/17/14
to chromi...@chromium.org
Hello,

I tried to do this with the Glyphicons Halflings font from Bootstrap so I could use it in my packaged app, but it didn't work.  Can you see why?

Thanks!

Mike


On Thursday, September 4, 2014 2:32:03 PM UTC-5, Libor Bus wrote:
app.css

Andrew B Goldberg

unread,
Jan 28, 2016, 8:07:15 PM1/28/16
to Chromium-Apps-Announce, schmal...@gmail.com
I know this is a really old post, but I was wondering if you ever got this working? I am facing the same exact issue (packaged app, angularjs application in a sandboxed iframe, trying to use @font-face and running into CORS errors). 

Thanks!
Andrew

Scott

unread,
Dec 4, 2016, 4:52:42 PM12/4/16
to Chromium-Apps-Announce, schmal...@gmail.com
Hey all.  This is a phenomenally old post, but since I just ran into the same problem too, and there doesn't seem to be anyone who has described how to solve all these problems, I thought I'd take a shot at it in the hope I can save someone else a day's worth of work.

This is what I've found.  Don't use <iframe> in packaged apps.  They sort of work, but as this thread has illuminated, <iframe>'s won't load fonts.  And there doesn't seem to be anything you can do about that.

What you probably want to do is use <webview>.  What you'll need to do to make it work correctly is the following:

1) In the permissions block in manifest.json, add "webview".
2) Add a webview block to manifest.json that looks something like this:

       
 "webview":
 
{
 
"partitions":
 
[
 {
 "name": "good_trusted",
 "accessible_resources":
 [
 "index.html",
 "app.js",
 "css/material-design-iconic-font/css/material-design-iconic-font.min.css",
 "css/material-design-iconic-font/fonts/Material-Design-Iconic-Font.woff",
 "css/material-design-iconic-font/fonts/Material-Design-Iconic-Font.woff2",
 "css/material-design-iconic-font/fonts/Material-Design-Iconic-Font.ttf"
 ]
 }
 ]
 },

In other words, list every resource your <webview>'d page is going to load in the webview block.

3) In the html that uses the <webview> tag, make it look something like this:

<!DOCTYPE HTML>
<html lang="en-US">
<head>
 
<meta charset="UTF-8">
 
<title>Title</title>
 
<script type="text/javascript" src="api.js"></script>
</head>
<body>
 
<webview id="iframe" partition="good_trusted" src="index.html" style="position:fixed; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;"></webivew>
 
<script type="text/javascript" src="bridge.js"></script>
</body>
</html>

That is pretty much it.  The HTML uses the "partition" property to reference back to information in manifest.json.  Then when the webview loads resources, Chrome seemingly checks against that list to accept or deny loading the resource.  After much headache, I finally got this to work and it seems to be behaving pretty well now.

Communication between the webview'd page and the app can happen using window.postMessage().  The one thing to note there is that the app must initiate the conversation because the webview doesn't seem to know who to postMessage() to, unless it receives a message from the app and can save the source of that message for use when it wants to initiate communication.  There are a few links around that illustrate how to do that.

Hope this helps someone, and if anything is confusing, let me know.

Take care,

Scott

April Lopp

unread,
Dec 4, 2016, 4:55:36 PM12/4/16
to Scott, schmal...@gmail.com, Chromium-Apps-Announce
This better be April lopp 

April lopp

--
You received this message because you are subscribed to the Google Groups "Chromium-Apps-Announce" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-apps+unsubscribe@chromium.org.

To post to this group, send email to chromi...@chromium.org.
Reply all
Reply to author
Forward
0 new messages