Using Express.js to serve simple SVG files (Technique involving Cheerio.js)

My goal is to manipulate SVGs before sending them through Express.js. The code snippet I am using is as follows:

app.get("/iconic/styles/:style/:base/:icon", function (req, res) {
    var style = req.params.style;
    var base = req.params.base;
    var icon = req.params.icon;

    var iconPath = path.join(iconFolderRoot, style, icon);

    svgProcessor(iconPath, base).then(function (svg) {
        //console.log(svg);  // SO: See the example output posted below

        res.header("Content-Type","image/svg+xml");

        //res.send(new Buffer(svg, 'binary')); // No difference

        res.send(svg);
    }).catch(function (err) {
        res.status(404).send("Error" + JSON.stringify(err, null, "  "));
    });
});

By not setting the res.header(), accessing the route in the browser works as expected (fits within the layout). However, I encounter issues when trying to embed them in an <img> tag unless the header is set.

When res.header() is set, embedding the image in an <img> tag does work, but the behavior is not as desired (fixed size).

Sending the file directly with res.sendFile(iconPath) functions correctly. I considered this might be due to the file needing to be sent as binary, which can be observed in

res.send(new Buffer(svg, 'binary'))
, however, it had the same outcome as res.send(svg).

The statement console.log(svg) displays the following code:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewbox="0 0 128 128" style="enable-background:new 0 0 128 128;" xml:space="preserve">
<style type="text/css">
        .st0{fill:#49C5B1;}
</style>
<title>Icons_TEST</title>
<g id="Example">
        <path {{{REMOVED FOR STACKOVERFLOW POST}}}/>
</g>
</svg>

An alternative solution could involve saving the file to a temporary directory and then utilizing res.sendFile(tempPath). However, I believe there must be a more efficient approach...

Below is a sample of the response header:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: image/svg+xml
Date: Thu, 20 Oct 2016 00:51:18 GMT
Connection: keep-alive
Content-Length: 3577

Answer №1

When I posted this question on the Express github page, a user mentioned that they were interested in the svgProcessor as a potential issue. I suspected that the problem might be related to how it was being served, so I attempted to address this by directly rendering the svg with

res.render(fs.readFileSync(iconPath))
. Surprisingly, this approach worked as expected.

I examined the output from the svgProcessor for quite some time but couldn't spot any differences, so I decided to use an online diffing tool which revealed the following:

https://i.sstatic.net/2FXH1.png

Even after having the solution right in front of me, I still couldn't identify the issue. It wasn't until I realized that the `B` in `viewBox` had been turned into lowercase. This unexpected behavior was caused by Cheerio (the package I was using for navigating through the svg nodes) normalizing the attributes.

Solution:

var $ = cheerio.load(svg, { xmlMode: true } );

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Some CSS styles are not displaying correctly within an iframe

Let me start by clarifying that I am not looking to add extra CSS to the contents of an iframe from the parent document. My issue lies with a document that normally displays correctly but experiences styling issues when shown in an iframe. Whenever I searc ...

making the div tag invisible when the if statement is satisfied

Is there a way to hide a <div> element if my data equals zero? I have an if condition set up as follows: if ($_SESSION['m1'] == 0) { I want the <div> tag to be deactivated, here is the code snippet for the <div> in question: ...

A guide on linking react-final-form to a backend system

Below is a form I created using react-final-form: import React from "react" import { Form, Field } from "react-final-form" import * as Yup from "yup" import axios from "axios" import Layout from "../components/layout" import servisStyles from "./servis.m ...

Should a MEAN stack app require the use of two servers in order to run?

Currently, I am in the process of developing a MEAN stack application which involves using MongoDB, ExpressJs, Angular 6, and NodeJs. One issue I am facing is determining whether two servers will be necessary to run the app simultaneously. Specifically, o ...

Issue with Bootstrap Scrollspy: Scrollspy function not functioning as expected

I need help with creating a one-page website where the navbar links change based on the section of the page you are on. I tried implementing it using HTML, but it didn't work out as expected. The code I used was within the container holding different ...

In PHP forms, ensure that only completed textboxes are submitted and empty textboxes are discarded

I've created a form that displays all available products from a database along with their prices. Users can input the quantity they want to purchase for each product, and upon submission, the total amount will be calculated. There are 5 products in th ...

Enhancing menu appearance on an ASP.NET platform

Applying styles to menu items has been a bit tricky for me. When I hover over the container, nothing seems to happen, even though the hover style is applied to the container. The action only takes place when I click on the text of the link. Stylesheet: ...

Issue with PHP Upload: Index is undefined

Having Trouble with PHP Upload: Encountered an issue: Undefined index: file in Error on line: $count = count($_FILES['file']['name']); Tried numerous codes to fix this error, but none have worked so far PHP Code: <?php $count ...

Aptana throws a fit over a script that's as empty as

Within Aptana, I am encountering an issue with the following line of code: <script type="text/javascript" charset="utf-8" src="js/jquery-1.7.2.js"></script> Alternatively, it could be written as: <script type="text/javascript" charset="ut ...

Differences between String Comparison in Node.js with "UTF-16"

Just starting out with Node.js and hoping to find an npm package or module that can compare two strings in UTF-16 format. In my C# code, I currently use the following function: public int Compare(string x, string y) { var myComparer = CompareInfo.Get ...

Create dynamic flex transitions

After searching through various CSS resources and websites, I haven't found an answer to my specific query. I have been exploring CSS tricks as well as http://n12v.com/css-transition-to-from-auto/ but still uncertain if what I'm looking to achiev ...

On the initial click of the button, the color will switch, and on the subsequent click,

I have created a basic HTML structure with a paragraph and a button. Upon clicking the button, I need different actions to take place. Specifically, on the first click, I want to change the color of the paragraph. On the second click, I aim to alter the fo ...

JavaScript function to toggle the visibility of navigation with a click of a button

I'm attempting to create a functionality in my code where the Open navigation button hides when the side navigation opens upon clicking. The desired behavior is for the openNav button to be hidden when it's clicked and then shown again when close ...

Unveiling the secret to extracting URL parameters from a POST request using Node.js and Express.js

REQUEST URL http://localhost:9090/rest-api/fetchDetailedProductInfo?prodId=1&tempId=123 fetchDetailedProductInfoEndpoint: function (prodId) { var self = this; var endpointURL = 'http://localhost:9090/ ...

Next route is being prioritized over the express route

Here is the configuration of my router setup: app.js global.express = require('express'); var app = express(); app.use(require('./server/routes/index')); index.js var router = express.Router(); router.use('/', require(&apo ...

Using Bootstrap4 to merge rows into a single column or apply rowspan in Bootstrap

Hey there, I have a specific requirement that I need help with. Check out the image here. I want to enable the LCM information box when the LCM checkbox is checked. Below is my code: <div class="panel-body "> <div class="c ...

JavaScript double-click functionality is not operational on IE9 and IE11 browsers

My JavaScript code has an issue where single-click opens a link in a new tab and double-click opens a lightbox. This works perfectly in all browsers except for IE9 and IE11. In my initial code, both single-click and double-click function correctly. However ...

Posix cannot be installed by Npm

Need help with installing posix as I'm encountering errors. Here's the link to see the errors: http://prntscr.com/2bnhwv Any suggestions on how to resolve this issue? ...

Utilizing Promises in the apply function

I am currently working on a project in Node.js that utilizes bluebird for promise handling, as well as ES6 native promises. In both projects, I have a chain where I make a database query structured like this: some_function(/*...*/) .then(function () ...

The npm -g list command is not showing any results, however, running npm list will display the

Having encountered a strange issue, I have been unable to locate a similar problem on Stack Overflow (which is quite unusual) so I decided to ask here. The npm -g list command does not display anything for me. Not even when using the --empty option. It ju ...