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:

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

Addressing memory leaks in React server-side rendering and Node.js with setInterval

Currently in my all-encompassing react application, there's a react element that has setInterval within componentWillMount and clearInterval inside componentWillUnmount. Luckily, componentWillUnmount is not invoked on the server. componentWillMount( ...

What is the best way to paginate aggregated results in Mongoose?

In my project, I have a User model that is linked to two other associated models - Profile and WorkProfile. The Profile model contains basic information about the user like name, email, and home address, while the WorkProfile model stores details such as o ...

Tips to prevent browser from freezing while creating a large number of HTML elements

I am currently utilizing Selection.js to develop a customizable grid on my website. To make this work effectively, I need a specific number of div elements to establish the selectable area. In my scenario, I generate all the divs using a for loop and then ...

What are the steps to address unhandled promise rejections?

Issue: UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token o in JSON at position 1 Currently working on a MERN stack application. The signup form is in the Frontend, and below is the POST method for it. const onSignUp = async (e) => { ...

Merging backend code (Java and Python) into HTML for seamless integration

While I have a solid background in back-end coding languages like Java and Python, the task at hand requires integrating this code into a website. The backend code comprises various methods and classes to encrypt text messages using encryption techniques ...

Tips for regaining access to a docker container

Currently, I have a Docker container running Ubuntu with a simple Node Express site. To connect to the container, I used the following command: docker run -i -t -p 8080:3000 node-express The Node app in the container is being managed by pm2, so it conti ...

Use npm to include a new dependency from the current dependency structure

I am currently working on a Vue application that utilizes both vuetable-2 and vue-axios. In my app.js file, I have the following imports: import Vue from 'vue' import VueMaterial from 'vue-material' import axios from 'axios' ...

How can I navigate through embedded MongoDB documents in Node.js to retrieve the values of their keys?

I'm facing an issue with multiple MongoDB documents related to each other. I need help accessing keys and values from the parent document down to the grandchild relational document. Here's the structure I have: const itemSchema = new mongoose.Sch ...

Creating a rotating circle in CSS with ion-slides: A step-by-step guide

Hello, I am attempting to develop a circular object that will rotate in the direction it is dragged. Within this circle, there are elements positioned along the border so that these elements also spin accordingly. To illustrate, below are the specific elem ...

Passing URL parameters from App.js to routes/index.js

I have a URL that looks like this: http://localhost:3000/?url=test In my Express application's app.js file, I'm attempting to extract the "test" parameter from the URL and pass it to my routes/index.js. Currently, I can easily send a static var ...

Tips for creating multiple full-screen overlays in HTML

I am new to the world of web development and I am currently working on implementing a set of buttons that will trigger specific overlays when clicked. I found the following code snippet on W3schools which creates a button along with an overlay effect. < ...

What's preventing me from using the left click function on my published blog post?

This is my first time creating a blogger template and everything seems to be working correctly. However, I have encountered one problem. For some reason, I am unable to left click on my blog post. I have not installed any right/left click disabler and I&a ...

What are the reasons for a Lambda function not being triggered when added as a target to an Event Bridge Rule?

I have encountered an issue with setting a rule and a lambda target for EventBridge. Although I have successfully added the rule and target, the Lambda is not being triggered. Additionally, when I look at the target Lambda function on the AWS Console, I do ...

The functionality of Access-Control-Allow-Origin is not effective in Chrome, yet it operates successfully in Firefox

I'm facing an issue with my code in the HTML file. I have a second file that I want to load content from, and both files are located in the same directory <div id="mainMenu"></div> <script> $(function() { $('#mainMe ...

Positioning the sDom in jQuery DataTables

Take a look at the image below: I want to adjust the position of the tableTools buttons (Copy, Excel, CSV) so that they appear aligned with the Search Box. I've experimented with different sDom parameters but haven't been successful. This is th ...

Difficulty Aligning Angular Material Expansion Panel with mat-nav-listI am facing an issue with

Currently, I have implemented a mat-nav-list to showcase the Menu items on my webpage. However, there seems to be an alignment issue with the 4th Menu item which is an Angular Material Expansion control. Refer to the screenshot provided below for clarifica ...

Removing the navigation button from the hamburger menu

I am working on creating a semi-progressive top navigation bar. For the mobile viewport, the navigation bar will only display the logo and a hamburger button. When the button is clicked, various navigation menu options as well as the Log In and Sign Up bu ...

Guide to setting up an express route to utilize passport for secure authentication

I've recently made some adjustments to a boilerplate I created in es6 by downgrading it to an older version, es5. During this process, I had to modify the way I handle exports and requires instead of using imports, but now the routing is working smoot ...

Tips for sending data to Jade templates:1. Use the `locals`

Review the code below user.js exports.index = function (req, res){ res.render('user', { id: req.params.id }); }; user.jade body - var x = #{id} div.container div.headpic if (x < 10) ...

Prevent the caching of the cache manifest file in IIS to avoid issues with browser caching

Looking for some advice on adding a cache manifest to my web app. I'll be deploying the app on IIS and need help making sure "that the cache manifest file is not cacheable by HTTP semantics" (source: ) Does anybody have tips on preventing a .appcache ...