Join Troy Miles for an in-depth discussion in this video Serving static content, part of Web Servers and APIs using C++.
So, we're gonna come over here, and we say New, Folder, and we'll say images. And then, again, public, New, Folder, scripts. And, third time's a charm, Folder, styles. Next, we need to generalize the code to read a file. Right now, it is part of the root route handler, and only reads the index.html file.
We need to modify it so it can read any file. Moreover, we need to put it in a function, so any handler can use it. Just above the main function, add a new one named sendFile. It returns void, and takes a response object and two strings, file name and content type. So, right here, just above the main, we're gonna say, void sendFile. It is going to take a response, and that's gonna be res, a string, filename, and another string, contentType.
And we'll open and close some curly brackets, do a little space between here and the other one. Next, what we're gonna do is, we're just gonna take this method right here from out of the root route handler, cut it, and paste it here, and instead of it being a hardcoded string, we're gonna say + filename, and we're gonna change this. We don't need the index.html anymore.
And then, we're gonna make another change right here, just above res.write, we're gonna put a res.set_header, and that is going to be our content type, so that when browsers get our files, they know what they are. So, Content-Type, and it's going to be the content type that got passed in, and we need a semicolon at the end there. Then, here in the Else clause, we're gonna say, res.code = 404, which is the universal sign for "Can't find that file".
We got an extra space right here, let's delete that. And that's our sendFile method, then just below it, we're gonna do a void sendHtml. It is going to take a response object and a file name. And then, it's gonna call sendFile with res, filename, and this time, what I'm gonna do is, I'm going to append a .html to the end of this and pass it in a content type, which is gonna be text/html.
Then, in here, in the root route, I'm going to say, sendHtml, and it is going to send the response object and the string index. And, let's put our semicolon there. There, now we've reduced the size of our route handler and made it easier to understand. So, let's add a few more helper functions, and they're gonna be very similar to send.html.
The first one is gonna be sendImage, so we'll make a copy of it first. We'll change the name to sendImage. Takes the same inputs, and we're gonna call sendFile, only now, what we're gonna do, we're not gonna append anything to the end, but we will prepend the subdirectory here. So, this is going to be images/.
The sendStyle, and this is going to be styles, and the style is going to be text/css. So, we got styles, scripts, images and HTML. Now, let's create a couple more routes that it uses. So, our first of these new routes is gonna be for styles.
So, it's gonna go /styles/, what's gonna come here is angle bracket, angle bracket, and in the middle of the angle bracket, it's gonna be a string. This is our first instance of a route parameter. The words string surrounded by angle brackets will capture whatever text is in the route at this position, and pass it to the handler method as a parameter. In our case, these two parameters are always gonna be present there, and then, the next one is going to be string filename.
It's important to know that you can also have ints here, doubles, and a few other variable types, and they must match, this string here must match here. If you had an int here, it would have to be an int here, and whatever string goes here has to be able to be cast to that type of variable. So, everything here can get cast to a string, so you're super safe there. And in this case, now we have our file name, and we are gonna call sendStyle.
We are gonna pass it, instead of index, filename. And then, we need to create a few more, just like this one. So, one and two. And, this one is going to be for scripts. Still gonna take that string, and instead of calling sendStyle, I'm gonna call sendScript.
And down here, gonna have images, and we're gonna call sendImage. All right, so we have all of our routes updated, and our helper functions complete, so let's add some test files. So, we're going to go into the styles. I'm gonna do a right-click, say New, File. Gonna name this file styles.css, and I'm gonna keep it short and simple. So, it's just gonna be a body, opening and closing brace, change the background color, and we're gonna make the background color light green.
There we go. And we're gonna go into index.html. Just before the closing head tag, we are going to create a link, and it is going to be a style sheet. And, its href is going to be styles/styles.css. Gonna have a closing angle bracket, then here, we're gonna say script source is going to equal scripts/test.js, and we'll close this script tag off.
Then, first off, let's go ahead and change our H1 tag just a little bit, so that we can always see the difference as we make our changes. Create an image tag, and the source is going to equal images/test.jpg. And then, we'll close off that tag, save this file, make sure we save off main.cpp, and then, go back to the terminal.
And that is how you add static content to a website.
- Working with Crow, the C++ micro web framework
- Deploying containers to Heroku
- Building websites and webpages
- Accessing data from a database
- Accessing data via RESTful APIs
- Creating API endpoints
- Running WebSockets on Heroku