Unable to Change Favicon with Express.js - node.js

This is a really basic question, but I'm trying to change the favicon of my node.js/Express app with
app.use(express.favicon(__dirname + '/public/images/favicon.ico'));
and I'm still getting the default favicon. This is in my app.configure function, and yes, I've verified that there is a favicon.ico in the /public/images/favicon.ico.There's nothing about a favicon.ico in the console, either, which leads me to believe that this line of code is being ignored. Everything else in the function (setting port, setting views directory, setting template engine. etc.) seems to be working fine, so why would this line of code not be executing?
What I tried
Emptying browser cache
Restarting Terminal and running node app.js again
Adding { maxAge: 2592000000 }, as described here
Thanks in advance.
Update: I got it to work. See my answer below for more information.

I tried visiting the site in Safari for the first time (I normally use Chrome) and noticed that it was showing the correct favicon. I tried clearing my cache in Chrome again (twice) to no avail, but after more searching, I found that apparently favicons aren't stored in the cache. I "refreshed my favicon" using the method described here and it worked!
Here's the method (modified from the above link), in case the link goes dead:
Open Chrome/the problematic browser
Navigate to the favicon.ico file directly, e.g. http://localhost:3000/favicon.ico
Refresh the favicon.ico URL by pressing F5 or the appropriate browser Refresh (Reload) button
Close the browser and open your website - voila, your favicon has been updated!

What worked for me finally:
Look that the
app.use(express.favicon(__dirname + '/public/images/favicon.ico'));
is at the beginning of the app configuration function. I had it before at the end. As the Express doc says: 'The order of which middleware are "defined" using app.use() is very important, they are invoked sequentially, thus this defines middleware precedence.'
I didn't need to set any maxAge.
To test it:
Restart the server with node app.js
Clear the browser cache
Refresh the Favicon with directly accessing it by using "localhost:3000/your_path_to_the favicon/favicon.ico" and reloading

The above answer is no longer valid.
If you use
app.use(express.favicon(__dirname + '/public/images/favicon.ico'));
You'll get this error:
Error: Most middleware (like favicon) is no longer bundled with Express and must be installed separately
What you're going to need to do is get serve-favicon.
run
npm install serve-favicon --save
then add this to your app
var express = require('express');
var favicon = require('serve-favicon');
var app = express();
app.use(favicon(__dirname + '/public/images/favicon.ico'));

smiley favicon to prevent error:
var favicon = new Buffer('AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA/4QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREQAAAAAAEAAAEAAAAAEAAAABAAAAEAAAAAAQAAAQAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD8HwAA++8AAPf3AADv+wAA7/sAAP//AAD//wAA+98AAP//AAD//wAA//8AAP//AAD//wAA', 'base64');
app.get("/favicon.ico", function(req, res) {
res.statusCode = 200;
res.setHeader('Content-Length', favicon.length);
res.setHeader('Content-Type', 'image/x-icon');
res.setHeader("Cache-Control", "public, max-age=2592000"); // expiers after a month
res.setHeader("Expires", new Date(Date.now() + 2592000000).toUTCString());
res.end(favicon);
});
to change icon in code above
make an icon maybe here: http://www.favicon.cc/ or here :http://favicon-generator.org
convert it to base64 maybe here: http://base64converter.com/
then replace the icon base 64 value
general information how to create a personalized fav icon
icons are made using photoshop or inkscape, maybe inkscape then photoshop for vibrance and color correction (in image->adjustments menu).
for quick icon goto http://www.clker.com/ and pick some Vector Clip Arts, and download as svg.
then bring it to inkscape and change colors or delete parts, maybe add something from another vector clipart image, then to export select the parts to export and click file>export, pick size like 16x16 for favicon or 32x32, for further edit 128x128 or 256x256. ico package can have several icon sizes inside. it can have along with 16x16 pixel fav icon a high quality icons for link for the website.
then maybe enhance the imaage in photoshop. like vibrance bivel round mask , anything.
then upload this image to one of the websites that generate favicons.
there are also programs for windows for editing icons(search like "windows icon editor opensource", figure our how to create two images of different size inside a single icon).
to add the favicon to website. just put the favicon.ico as a file in your root domain files folder. for example in nodejs in public folder that contans the static files. it doesn't have to be anything special like code above just a simple file.

What worked for me follows. Set express to serve your static resources as usual, for example
app.use(express.static('public'));
Put favicon inside your public folder; Then add a query string to you icon url, for example
<link rel="icon" type="image/x-icon" href="favicon.ico?v="+ Math.trunc(Math.random()*999)>
In this case, Chrome is the misbehaving Browser; IE. Firefox. Safari (all on Windows) worked fine, WITHOUT the above trick.

Simplest way I could come up with (valid only for local dev, of course) was to host the server on a different port
PORT=3001 npm run start

Have you tried clearing your browser's cache? Maybe the old favicon is still in the cache.

How to do this without express:
if (req.method == "GET") {
if (/favicon\.ico/.test(req.url)) {
fs.readFile("home/usr/path/favicon.ico", function(err, data) {
if (err) {
console.log(err);
} else {
res.setHeader("Content-Type","image/x-icon");
res.end(data);
}
});
}

Related

Why is Chrome treating this file as document, while Firefox as Image?

I have a download GET endpoint in my express app. For now it simply reads a file from the file system and streams it after setting some headers.
When i open the endpoint in Chrome, I can see that this is treated as a "document", while in Firefox it is being treated as type png.
I can't seem to understand why it is being treated differently.
Chrome: title bar - "download"
Firefox: title bar - "image name"
In Chrome, this also leads to no caching of the image if I refresh the address bar.
In Firefox it is being cached just fine.
This is my express code:
app.get("/download", function(req, res) {
let file = `${__dirname}/graph-colors.png`;
var mimetype = "image/png";
res.set("Content-Type", mimetype);
res.set("Cache-Control", "public, max-age=1000");
res.set("Content-Disposition", "inline");
res.set("Vary", "Origin");
var filestream = fs.createReadStream(file);
filestream.pipe(res);
});
Also attaching images for Browser network tabs.
This are all to do with the behaviors of Chrome, you can test on another site like Example.png on Wikipedia.
Chrome always treats the "thing" you opened in the address bar as document, ignoring what it really is. You can even test loading a css and it will read document.
For title, it reads download because your path is /download, you cannot change it according to this SO thread.
For caching, Chrome apparently ignores the cache when you are reloading, anything, page or image. You can try using the Wiki example.png, you will get 304 instead of "(from cache)". (304 means the request is sent, and the server has implemented ETag, if-none-match or similar technique)

Socket.io does not work on deploying to Heroku [duplicate]

Why am I getting this error in console?
Refused to execute script from
'https://www.googleapis.com/customsearch/v1?key=API_KEY&q=flower&searchType=image&fileType=jpg&imgSize=small&alt=json'
because its MIME type ('application/json') is not executable, and
strict MIME type checking is enabled.
In my case it was a file not found, I typed the path to the javascript file incorrectly.
You have a <script> element that is trying to load some external JavaScript.
The URL you have given it points to a JSON file and not a JavaScript program.
The server is correctly reporting that it is JSON so the browser is aborting with that error message instead of trying to execute the JSON as JavaScript (which would throw an error).
Odds are that the underlying reason for this is that you are trying to make an Ajax request, have hit a cross origin error and have tried to fix it by telling jQuery that you are using JSONP. This only works if the URL provides JSONP (which is a different subset of JavaScript), which this one doesn't.
The same URL with the additional query string parameter callback=the_name_of_your_callback_function does return JavaScript though.
This result is the first that pops-up in google, and is more broad than what's happening here. The following will apply to an express server:
I was trying to access resources from a nested folder.
Inside index.html i had
<script src="./script.js"></script>
The static route was mounted at :
app.use(express.static(__dirname));
But the script.js is located in the nested folder as in: js/myStaticApp/script.js
I just changed the static route to:
app.use(express.static(path.join(__dirname, "js")));
Now it works :)
Try to use express.static() if you are using Node.js.
You simply need to pass the name of the directory where you keep your static assets, to the express.static middleware to start serving the files directly. For example, if you keep your images, CSS, and JavaScript files in a directory named public, you can do as below −
i.e. : app.use(express.static('public'));
This approach resolved my issue.
In my case, I was working on legacy code
and I have this line of code
<script type="text/javascript" src="js/i18n.js.php"></script>
I was confused about how this supposed to work this code was calling PHP file not js
despite it was working on the live server
but I have this error on the stage sever
and the content type was
content-type: text/html; charset=UTF-8
even it is text/javascript in the script tag
and after I added
header('Content-Type: text/javascript');
at the beginning for file i18n.js.php
the error is fixed
After searching for a while I realized that this error in my Windows 10 64 bits was related to JavaScript. In order to see this go to your browser DevTools and confirm that first. In my case it shows an error like "MIME type ('application/javascript') is not executable".
If that is the case I've found a solution. Here's the deal:
Borrowing user "ilango100" on https://github.com/jupyterlab/jupyterlab/issues/6098:
I had the exact same issue a while ago. I think this issue is specific to Windows. It is due to the wrong MIME type being set in Windows registry for javascript files. I solved the issue by editing the Windows registry with correct content type:
regedit -> HKEY_LOCAL_MACHINE\Software\Classes -> You will see lot of folders for each file extension -> Just scroll down to ".js" registry and select it -> On the right, if the "Content Type" value is other than application/javascript, then this is causing the problem. Right click on Content Type and change the value to application/javascript
enter image description here
Try again in the browser."
After that I've realized that the error changes. It doesn't even open automatically in the browser anymore. PGAdmin, however, will be open on the side bar (close to the calendar/clock). By trying to open in the browser directly ("New PGAdmin 4 window...") it doesn't work either.
FINAL SOLUTION: click on "Copy server URL" and paste it on your browser. It worked for me!
EDIT: Copying server URL might not be necessary, as explained by Eric Mutta in the comment below.
I accidentally named the js file .min instead of .min.js ...
Python flask
On Windows, it uses data from the registry, so if the "Content Type" value in HKCR/.js is not set to the proper MIME type it can cause your problem.
Open regedit and go to the HKEY_CLASSES_ROOT make sure the key .js/Content Type has the value text/javascript
C:\>reg query HKCR\.js /v "Content Type"
HKEY_CLASSES_ROOT\.js
Content Type REG_SZ text/javascript
In my case (React app), just force cleaning the cache and it worked.
I had my web server returning:
Content-Type: application\javascript
and couldn't for the life of me figure out what was wrong. Then I realized I had the slash in the wrong direction. It should be:
Content-Type: application/javascript
In my case, while executing my typescript file,
I wrote:
<script src="./script.ts"></script>
Instead of:
<script src="./script.js"></script>
In my case Spring Security was looking for authentication before allowing calls to external libraries. I had a folder /dist/.. that I had added to the project, once I added the folder to the ignore list in my WebSecurityConfig class, it worked fine.
web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**", "/error", "/dist/**");
Check for empty src in script tag.
In my case, i was dynamically populating src from script(php in my case), but in a particular case src remained empty, which caused this error. Out was something like this:
<script src=""></script> //empty src causes error
So instead of empty src in script tag, I removed the script tag all together.
Something like this:
if($src !== ''){
echo '<script src="'.$src.'"></script>';
}
You can use just Use type
or which you are using you choose that file type
My problem was that I have been putting the CSS files in the scripts definition area just above the end of the
Try to check the files spots within your pages
I am using SpringMVC+tomcat+React
#Anfuca's answer does not work for me(force cleaning the browser's cache)
I used Filter to forward specific url pattern to the React's index.html
public class FrontFilter extends HttpFilter {
#Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
boolean startsWithApi = requestURI.startsWith("/api/");
boolean isFrontendUri = requestURI.startsWith("/index.html");
if (!startsWithApi && !isFrontendUri) {
req.getRequestDispatcher("/index.html").forward(req, res);
}
super.doFilter(wrapped, res, chain);
}
}
There is no Spring Security problem bcs my filter executes before Spring Security's
but I still see the same error and find here
Then I realized that I forgot adding one more condition for JS and CSS:
boolean startsWithStatic = requestURI.startsWith(contextPath + "/static");
Add this to my if condition and problem solved, no more error with MIME type or ('text/html') with js and css
Root cause is that I incorrectly forward JS and CSS type to HTML type
I got the same error. I realized my app.js was in another folder. I just moved it into that folder where my index.html file is and it resolved.
In Angular Development try this
Add the code snippet as shown below to the entry html. i.e "index.html" in reactjs
<div id="wrapper"></div>
<base href="/" />
If you have a route on express such as:
app.get("*", (req, res) => {
...
});
Try to change it for something more specific:
app.get("/", (req, res) => {
...
});
For example.
Or else you just might find yourself recursively serving the same HTML template over and over...
In my case I had a symlink for the 404'd file and my Tomcat was not configured to allow symlinks.
I know that it is not likely to be the cause for most people, but if you are desperate, check this possibility just in case.
I hade same problem then i fixed like this
change "text/javascript"
to
type="application/json"
I solved my problem by adding just ${pageContext.request.contextPath} to my jsp path .
in stead of :
<script src="static/js/jquery-3.2.1.min.js"></script>
I set :
<script src="${pageContext.request.contextPath}/static/js/jquery-3.2.1.min.js"></script>

Routing in locomotive using ejs

I'm trying out node and some frameworks for node atm, specifically locomotive. However, i seem to be stuck on routing using locomotive. A couple questions i can't find the answer to, so here goes:
why does the locomotive out-of-box install use index.html.ejs as a
filename? Why not just index.ejs? What's the benefit?
i'm trying to add a route to a view: searchName.html.ejs which i
added in the views folder. To achieve this i made a toolController
like this:
var locomotive = require('locomotive').Controller,
toolController = new Controller();
toolController.searchName = function() {
this.render();
}
module.exports = toolController;
I also added a route in routes.js like so:
this.match('searchName', 'tool#searchName');
However, that doesn't work (and yet it's what the documentation says ought to work). The result is a 404 error. So how do i make that route work?
Suppose i want to make a route to eg, anExample.html? How do i go
about that? I notice that in the out-of-the-box app from
locomotive, you cannot enter localhost:3000/index.html . Nor even
localhost:3000/index This seems highly impractical to me, as there
are plenty of users who'll add the specific page they want to go to.
So how can i make that work?
PS: I went through all questions regarding this on stackoverflow and searched the web, but i still can't figure this out.enter code here
The benefit is that this naming scheme allows you to specify several different formats for a single route. So you could have search_name.html.ejs and search_name.xml.ejs, then respond with either view depending on what your client is expecting.
There are a couple issues with the example code you posted. You should be seeing a more descriptive error than a 404, so I'm not sure what's happening there, but here are the fixes to your code that work in my environment.
In the controller:
//tool_controller.js
var locomotive = require('locomotive');
var toolController = new locomotive.Controller();
toolController.searchName = function() {
this.render();
};
module.exports = toolController;
In routes.js:
//routes.js
module.exports = function routes()
{
this.match('searchName', 'tool#searchName');
}
Then, you'll need to change the view to this: views/tool/search_name.html.ejs. It's not clear from the documentation, but locomotive automatically lowercases and underscores actions that are camel-cased, like searchName.
Now start the app and browse to http://localhost:3000/searchName
If you just want to serve a static html file, the easiest way is to just drop it in the public folder. This folder is specifically for serving up static content like client-side js, css, etc. And it works just fine for serving static HTML as well.

Adding views in Express/ejs

Basic question time:
I'm new to node.js/express/ejs.
How do I add a new ejs powered page to my server?
Example: I want to have a new page on my server that shows up as mysite.com/foo.html, and I want it to be rendered through app.router & ejs. How do I add this page and start to edit it?
I've started by working from the example of index.*js* that comes with the default express --ejs install. But digging into that code, 'find ./ -name "index.*js*"' comes up with no less than 25 different files that might be involved in producing that two-line index page.
Start me on the right path?
In your views directory add a file named foo.ejs and add the EJS you want to be rendered.
Then create another file named foo.js in the routes directory. Here is what the content
module.exports.index = function(req, res){
res.index('foo');
};
In the main express app file (the one you run via node app.js) first require the new route
var foo = require('./routes/foo');
then tell express about it
app.get('/foo.html', foo.index);

Yeoman - Javascript loading error

This is my app structure.
Yeoman with angular and coffee server(node+express) which gets view and public files via /app/.
View files:
app.set("view_engine", "html").engine "html", (path, options, fn) ->
if "function" is typeof options
fn = options
options = {}
fs.readFile path, "utf8", fn
Public files:
app.use express.static(path.resolve(__dirname + "/app/"))
I do load a lot of components like bootstrap, theme files,etc. HOwever, Javascript inside a view file doesnt work. It does work normally.
For example, if i remove and replace with for morris charts, it works. The same with ng-app and a view file with does not load the chart.
I think the problem is loading the js files first, since when i tried logging, the javascript file sends message before the controller for the view. So i guess the js file loads before the view thereby making the id inaccessible for the javascript file.
Please tell me how to solve this. It has been bugging me for over two days.
Thanks in advance.
Probably answered here: https://stackoverflow.com/a/12200540/1794563
Are you including jQuery before angularJS? If not, angularJS is using jqLite, which won't handle a situation like that.

Resources