Partial Text is not rendering correct on a site.
From browser:
From phantomjs:
Machine :Fedora 64 bit
Phantomjs version : 1.9.7
Dependencies already installed :
yum install urw-fonts
sudo yum install fontconfig freetype libfreetype.so.6 libfontconfig.so.1 libstdc++.so.6
On another Windows platform works fine, only issues with Linux environment. What am i missing?
I was having a problem with phantomjs and rendering of fonts for special characters (Japanese, Chinese, Hindi, etc.), and that's how I solved the problem:
Download the corresponding .ttf Unicode fonts file. There are several free sites on the web, but you have several Unicode fonts free files for several different character maps here.
Save the .ttf files in your server/machine either in the directory /etc/fonts or in the directory ~/.fonts. The latter is also a unix directory, if it does not exist, create it, and you need it if you have no root privileges (shared server for example)
Run either fc-cache -fv /etc/fonts or fc-cache -fv ~/.fonts/ accordingly. This fc-cache command scans the font directories on the system and builds font information cache files
Then in the phantomjs code, use always utf-8 either for file system
var HTMLfile = fs.open(path + file_name, {
mode: 'r', //read
charset: 'utf-8'
});
var content = HTMLfile.read();
HTMLfile.close();
or for webpage
var webPage = require('webpage');
var page = webPage.create();
var settings = {
operation: "POST",
encoding: "utf8",
headers: {
"Content-Type": "application/json"
},
data: JSON.stringify({
some: "data",
another: ["custom", "data"]
})
};
After long search, it worked for me.
Related
I'm building a Vue.js application using Vuexy BootstrapVue template, deployed in a Docker container.
I am finding that when we deploy updates to our web app, that the User has to do a hard-refresh in their browser to load the latest version of the app, otherwise they'll be navigating around a cached version.
Is there a way for me to force a client browser to load the latest version for a User?
Either on every load, or every few hours?
(I've tagged Bootstrap-Vue for transparency, but don't actually know if it has any bearing on this issue)
You are facing the cache problem and there is multiple ways to handle this.
Cache Control
You can control the cache with the header with max-age or no-store, no-cache to simple disable it, like this question/answer: How do we control web page caching, across all browsers?
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
https://csswizardry.com/2019/03/cache-control-for-civilians/
Cache busting
Aappending a version (example: 1.0.0) to query string of the script tag:
<script src="path/to/your/app.min.js?v=1.0.0"
and change that version for every build.
Hashing the script file
You can also use some webpack/rollup config to build the script with a hash, like app.bf43112.js
webpack
const config = {
output: {
path: PATHS.build,
filename: "[name].[contenthash].js",
},
};
Rollup
const isProduction = process.env.NODE_ENV === 'production';
export default {
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: isProduction ? 'bundle[hash].js' : 'public/build/bundle.js',
}
};
Reference: Hashed file names using Rollup
Service Worker
Another solution, that I never tested, but sounds a good method.. is creating a service worker to control how retrieve the js file:
https://developers.google.com/web/ilt/pwa/caching-files-with-service-worker
You can do things like deleting the cache, responding the cache with a response that you manually fetch with js, etc.
I've been rendering jsreport PDFs succesfully on my development machine. However, when running jsreport on the test server PhantomJS is falling back the use the default font. Any idea how to solve or troubleshoot?
I'm using Handlebars and PhantomJS. Dev machine spec: jsReport 1.0.7 on Node v4.4.5 on 64 bit Win10. Test server spec: jsReport 1.0.7 on Node vx.x.x on 64 bit Win2012 R2 Server
Steps to reproduce:
1) Upload fonts to jsReport
fonts uploaded to jsreport
When selected, jsReport suggests using it as below:
{#image MavenPro-Black #encoding=base64}
2) Add the “Shortcut” to the data file
{
"assets": {
"MavenPro-Black": "{#image MavenPro-Black}",
"MavenPro-Bold": "{#image MavenPro-Bold}",
"MavenPro-Medium": "{#image MavenPro-Medium}",
"MavenPro-Regular": "{#image MavenPro-Regular}",
"jquery": "{#image jquery}"
},
……
}
3) Use the asset in the Report
<head>
<script src="{{assets.jquery}}"></script>
<style>
/* Common Classes */
#font-face {
font-family: 'Maven Pro';
src: url({{assets.MavenPro_Regular}}) format('truetype');
}
The reason that it works on your local is because you have probably this font already installed. The reason why it cannot work on the server is because you have typo in your code:
You data includes property MavenPro-Regular, but in template you access it using {{assets.MavenPro_Regular}}. You just need to change - to _ in your data and it should work.
Working example:
https://playground.jsreport.net/studio/workspace/SklZyycYg/9
Hint 1: Use text recipe and print the raw output to troubleshoot such problems. You would immediately see that the url of font is not filled.
Hint 2: You should consider using jsreport assets feature to embed fonts rather than images extension. You can find demo how to use it with description here.
Edit
Assets extension is part of the default installation and can be considered stable since version 1.3.0
I'm trying to serve a favicon and some fonts.
object Lion : AbstractVerticle() {
#JvmStatic
#Throws(IOException::class)
fun main(args: Array<String>) {
val vertx = Vertx.vertx()
val router = Router.router(vertx)
router.route().handler(CorsHandler.create("*")
.allowedMethod(HttpMethod.GET)
.allowedMethod(HttpMethod.POST)
.allowedMethod(HttpMethod.OPTIONS)
.allowedHeader("X-PINGARUNER")
.allowedHeader("Content-Type"))
// some json GET / POST routes here
router.route().handler(FaviconHandler.create());
router.route().handler(StaticHandler.create())
vertx.createHttpServer().requestHandler { router.accept(it) }.listen(9090)
}
The FaviconHandler throws an exception causing an "Internal Server Error" when I go to http://localhost:9090/favicon.ico
My favicon is located in src/main/resources/webroot/favicon.ico
Oct 22, 2016 11:16:42 PM io.vertx.ext.web.impl.RoutingContextImplBase
SEVERE: Unexpected exception in route
java.lang.RuntimeException: java.lang.NullPointerException
at io.vertx.ext.web.handler.impl.FaviconHandlerImpl.init(FaviconHandlerImpl.java:148)
at io.vertx.ext.web.handler.impl.FaviconHandlerImpl.handle(FaviconHandlerImpl.java:155)
at io.vertx.ext.web.handler.impl.FaviconHandlerImpl.handle(FaviconHandlerImpl.java:33)
at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:215)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:78)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:94)
at io.vertx.ext.web.handler.impl.CorsHandlerImpl.handle(CorsHandlerImpl.java:121)
at io.vertx.ext.web.handler.impl.CorsHandlerImpl.handle(CorsHandlerImpl.java:38)
at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:215)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:78)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:94)
at io.vertx.ext.web.impl.RouterImpl.accept(RouterImpl.java:79)
at Lion$main$8.handle(Lion.kt:90)
at Lion$main$8.handle(Lion.kt:43)
at io.vertx.core.http.impl.ServerConnection.handleRequest(ServerConnection.java:286)
at io.vertx.core.http.impl.ServerConnection.processMessage(ServerConnection.java:412)
at io.vertx.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:139)
at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.lambda$createConnAndHandle$1(HttpServerImpl.java:712)
at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:314)
at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:190)
at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.createConnAndHandle(HttpServerImpl.java:706)
at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:570)
at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:522)
at io.vertx.core.http.impl.VertxHttpHandler.channelRead(VertxHttpHandler.java:76)
at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:122)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:372)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:358)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:350)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:372)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:358)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:350)
at io.vertx.core.http.impl.HttpServerImpl$Http1xOrHttp2Handler.http1(HttpServerImpl.java:1019)
at io.vertx.core.http.impl.HttpServerImpl$Http1xOrHttp2Handler.channelRead(HttpServerImpl.java:990)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:372)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:358)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:350)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:372)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:358)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:129)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:610)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:551)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:465)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:437)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at io.vertx.ext.web.handler.impl.FaviconHandlerImpl$Icon.<init>(FaviconHandlerImpl.java:61)
at io.vertx.ext.web.handler.impl.FaviconHandlerImpl$Icon.<init>(FaviconHandlerImpl.java:40)
at io.vertx.ext.web.handler.impl.FaviconHandlerImpl.init(FaviconHandlerImpl.java:143)
... 48 more
Removing the FaviconHandler and normal html, js and css files are serving fine, but fonts are failing to serve.
Failed to decode downloaded font: http://localhost:9090/fonts/glyphicons-halflings-regular.woff
/#/tcr:1 OTS parsing error: incorrect file size in WOFF header
When I go directly to that font-url, the browser is trying to download the font as a regular file.
This seems like a potential solution, but I'm seeing something that is not my favicon, just a 16x16 square with distorted lines in it, the fonts are still trying to download and still giving the error in the browser console.
router.route("/favicon.ico").handler {
it.response().putHeader("Content-Type", "image/x-icon").sendFile("webroot/favicon.ico")
}
router.route("/fonts/glyphicons-halflings-regular.woff").handler {
it.response().putHeader("Content-Type", "application/font-woff").sendFile("webroot/fonts/glyphicons-halflings-regular.woff")
}
So to sum up, how do I make the StaticHandler serve .woff and .ico files correctly with the correct MimeTypes and not have it download those files?
Solution:
First problem I had was that maven shade wasn't copying all the font files into jar for some reason.
Explicitly copying the font files on build and disabling resource filtering for fonts seems to have fixed the font issue.
<build>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>${basedir}/src/main/resources/fonts</directory>
<filtering>false</filtering>
</resource>
</resources>
Then serving the fonts from the resource directory instead of the font directory fixed it (VertX just wouldn't serve from the font directory for some reason even though the files are there)
router.route("/fonts/glyphicons-halflings-regular.woff2").handler {
it.response().sendFile("glyphicons-halflings-regular.woff2")
}
router.route("/fonts/glyphicons-halflings-regular.woff").handler {
it.response().sendFile("glyphicons-halflings-regular.woff")
}
router.route("/fonts/glyphicons-halflings-regular.ttf").handler {
it.response().sendFile("glyphicons-halflings-regular.ttf")
}
router.route().handler(StaticHandler.create().setCachingEnabled(true));
Favicon is probably being cached, still investigating, favicon is not that critical to fix at the moment.
router.route("/favicon.ico").handler(FaviconHandler.create("favicon.ico"))
Favicon.ico:
Simply move your favicon.ico file up a level into the resources folder directly:
/src/main/resources/favicon.ico
Alternatively change your FaviconHandler to pass in the path and filename:
router.route().handler(FaviconHandler.create(FaviconHandler.create("webroot/favicon.ico")))
Your code assumes that FaviconHandler also respects the webroot set in StaticHandler but it does not. That is purely a property of StaticHandler and therefore FaviconHandler looks for the resource in resources/ unless you specify a relative path. When that resource isn't found, it uses the result of getResourceAsStream("favicon.ico") which is null and crashes.
If you look at the unit test for the FaviconHandlerImpl you will see that they place the favicon.ico file in the root of resources instead of webroot.
WOFF Files:
As for your font files you are looking in the wrong place for the problem. It has nothing to do with MIME types.
More likely is that you corrupted the WOFF files on accident. This could have happened when you committed them with GIT and it thought they were text files and it broke the line endings thereby corrupting them. Or you used Maven Filter plugin and it did the same, corrupting them. Or you uploaded/downloaded them via FTP as text files, same problem.
See other posts about this: https://stackoverflow.com/a/33792610/3679676
You don't specify your favicon path, so Vertx tries to locate the default one:
if (path == null) {
icon = new Icon(Utils.readResourceToBuffer("favicon.ico"));
}
Your favicon is located at resources/webroot/favicon.ico, but Vertx looks for it at resources/favicon.ico
So you can either specify FaviconHandler.create("webroot/favicon.ico") or move it one directory up.
Regarding WOFF files, I was unable to reproduce the problem, as WOFF returns with application/x-font-woff, which seems correct.
I am using node-webkit to develop apps for my students, and to provide one stop solution I would need to update node-webkit archive once in a month. Is there a way I can accomplish that?
Basically I need to replace just one html file every month, say "page1.html".
I googled but have no idea where to start.
On Mac, you can access the filesystem of the own app e.g.
$ ls -lh /Applications/Shock.app/Contents/Resources/app.nw/
[...]
-rw-r--r-- 1 jordi staff 2,3K 29 gen 01:47 index.html
-rw-r--r-- 1 jordi staff 467B 29 gen 01:47 lecturenotes.html
[...]
So if you put a new version on a specific URL, you could fetch it and rewrite the HTML file inside the app:
var request = require('request');
request('http://www.your-own-server.com/app/lecturenotes.html', function (error, response, body) {
if (!error && response.statusCode == 200) {
var fs = require('fs');
fs.writeFileSync('/Applications/Shock.app/Contents/Resources/app.nw/lecturenotes.html', body);
}
});
I think something similar happens on Linux. Unfortunately, the Windows version works with a binary package into the exe, so this trick won't work for the last case.
I have used App.dataPath as described in https://github.com/nwjs/nw.js/wiki/App
You can download the html files into that path. App.dataPath works platform independent , though the location is different based on the platforms , your app will have a generic path to refer the html files.
excerpt :
Get the application's data path in user's directory. Windows:
%LOCALAPPDATA%/; Linux: ~/.config/; OSX: ~/Library/Application
Support/ where is the field in the manifest.
I want to upload a file to s3 so I want to run the upload program from this article:
http://www.componentix.com/blog/9
For this I need to install the multipart module.
https://github.com/isaacs/multipart-js
But by doing npm install multipart it is giving error
How should I install this multipart module so that I can get this program running?
You can download the full repo (not just the lib folder) into your application under a folder with the name node_modules.
Once you do that, your require will just be:
var multipart = require('multipart');
This is due to the way node resolves module dependencies. It will always look for a node_modules directory at the root of your app (and a few other places as well).
It's important you download the full repo and not just the lib folder if you plan to use it this way since the package.json file is used to find the main entry point.
{ "name" : "multipart"
, "version" : "0.0.0"
, "description" : "A JavaScript library for parsing and writing multipart messages"
, "contributors" :
[ "Isaac Z. Schlueter <i#izs.me>"
, "John Wright <mrjjwright#gmail.com>"
]
, "repository" :
{ "type" : "git"
, "url" : "http://github.com/isaacs/multipart-js.git"
}
, "main" : "lib/multipart"
}
The advantage of this is compatibility with using npm install locally in your dev machine.
You can also download the tar file form github. Hit the Download button and deploy that with your app. Once that is done in your server you can run
npm install <path-to-the-tar-file>
That will install multipart on the machine for you.
Download lib folder from the https://github.com/isaacs/multipart-js (including all the files inside it).
Put all those files next to your node application in the same folder.
On the top of your application file where you have included other modules like HTTP etc. ..append this >
var multipart = require("./multipart")