Firebase function - How to include external style.css in index.js - javascript

External style.css file is not working after deploying on server
My index.js and styles.css is in same directory.
index.js
const functions = require('firebase-functions');
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send(
`<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
Hello ...
</body>
</html>
`);
});

Cloud Functions HTTP triggers do not serve static content (such as HTML, CSS, and JS files) by default. HTTP triggers are primarily intended for you to write code that responds to HTTP requests, like API calls.
If you want to serve static content along with HTTP requests, you should look into using Firebase Hosting along with Cloud Functions. Firebase Hosting will serve your static content, and when configured properly, it will also forward some URLs to Cloud Functions that can be serviced by code you write.
Your other option is to configure an express app in Cloud Functions, and set up some routes with it so that incoming requests that go directly to Cloud Functions can be served by content that you deployed with your functions. But I think using Firebase Hosting is probably the more common and useful option.

Related

Javascript: Changing script type to "module" fails to fetch authenticated route [duplicate]

This question already has answers here:
Javascript ES6 modules not passing along .htaccess basic authentication
(2 answers)
Closed 3 months ago.
I have an express server that serves static HTML/JS files along with a REST API. Some of the routes to the static files requires authenticated request (via Bearer JWT token). I needed to change the type of the script to module in one of the HTML files to import another script, however after doing this the browser is not able to load the script anymore as it fails to bypass the authentication middleware.
Example:
<html>
<head>
<link rel="stylesheet" href="index.css" />
<script src="index.js" defer></script>
</head>
</html>
index.js:
import {foo} from "../another-script.js"
window.onLoad(() => foo());
The server is able to fetch the index.js (however it fails on line 1 since it is not of type module)
If I change it to:
<html>
<head>
<link rel="stylesheet" href="index.css" />
<script src="index.js" type="module"></script>
</head>
</html>
It fails to fetch the index.js and instead fetches the "Not Authenticated" HTML page.
What is going on here? Why does changing the type to module mean that it is unable to import a protected route?
As answered by #napubza in Javascript ES6 modules not passing along .htaccess basic authentication adding crossorigin to the script tag worked.

Uncaught TypeError: fs.writeFile is not a function

I am getting the error Uncaught TypeError: fs.writeFile is not a function in my program, in which I just want to write something to a JSON file. The fs.readFileSync function works properly, but fs.writeFile doesn't for some reason. Here is my code:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>Hello World!</h1>
<button id="button">Write Something</button>
<script src="./app.js"></script>
</body>
</html>
JavaScript:
const fs = require("fs");
const data = fs.readFileSync("db.json", "utf8");
const db = JSON.parse(data);
console.log(db);
document.getElementById("button").onclick = () => {
fs.writeFile("db.json", "test", () => {
console.log("Written file!");
});
};
JSON:
["something1", "something2"]
Just to let you know, I am using Parcel as my bundler. Please help me on why this is not working.
The Node.js fs module is not written in JavaScript. It is a core part of Node.js written in C/C++. It won't run in a web browser and can't be bundled into a JS file.
(Note that readFileSync can be inlined, it just reads the file when it is bundled instead of at runtime).
If you want to generate a JSON file then you can either:
Write a web service (which will write JSON to a file on the server) and then issue an HTTP request to it or
Convert the data into a downloadable URL (so it will be saved to the user's download folder).
You won't be able to use writeFile in the browser, even if you use a bundler because this is Node.js and not a browser API. Bundlers won't embed native Node.js functions in a browser's build because these are two different execution environments.
In the browser, you can't trigger arbitrarily a file write on the disk without the user's consent, so you have to actually trigger a file download instead.

Socket.io - socket.io.js not available

I need to get a socket.io server running using python.
I followed this example:
https://tutorialedge.net/python/python-socket-io-tutorial/
With the final files looking as follows:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<button onClick="sendMsg()">Hit Me</button>
<!--WORKS:-->
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>-->
<!-- DOESNT WORK:-->
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
<script>
const socket = io("http://localhost:8080");
function sendMsg() {
socket.emit("message", "HELLO WORLD");
}
socket.on("message", function(data) {
console.log(data);
});
</script>
</body>
</html>
server.py
from aiohttp import web
import socketio
sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)
async def index(request):
with open('index.html') as f:
return web.Response(text=f.read(), content_type='text/html')
#sio.on('message')
async def print_message(sid, message):
print("Socket ID-: " , sid)
print(message)
await sio.emit('message', message[::-1])
app.router.add_get('/', index)
if __name__ == '__main__':
web.run_app(app)
So much this is only copy paste and thus works fine, but I dont want to use the script from some online source. So I tried to modify the src of the script by commenting out the running version and replacing it by a version using a local socket.io.js.
As I did not find the script on my machine I found the following questions, that both did not help me solve my issue:
node-js-socket-io-socket-io-js-not-found
socket-io-not-being-served-by-node-js-server
No matter what I do I get the following error in my browser:
GET http://localhost:8080/node_modules/socket.io/socket.io.js net::ERR_ABORTED 404 (Not Found)
(index):18 Uncaught ReferenceError: io is not defined
at (index):18
(anonymous) # (index):18
From what I understood from the 2 linked threads, my server should provide the socket.io/socket.io.js when listen is called on the server.
Unfortunately this is not happening in my case.
I had socket.io installed via pip, I also tried npm install socket.io --save as suggested, this gives me a new folder 'node_modules', but modifying the src for my script to:
<script src="http://localhost:8080/node_modules/socket.io/socket.io.js"></script>
doesnt help either.
For some reason using the fie from cdnjs works just fine (see my index.html).
I would be very glad if someone could help me out with this.
Cheers
Chris
I've never worked with AIOHTTP (always worked with flask-socketio) so I did some research using the documentation. It turns out that like a lot of http server, AIOHTTP doesn't serve static files out of the box.
You will thus need to take care of it using the add_static method (doc here).
(Note that if you want to deploy this app for production it would be better practice to use an HTTP server like Apache or Nginx).
Just add this line under your routes declarations.
app.router.add_static('/static/', path='static/')
Now you need to create a static folder in the root of your project and put your socket.io.js file inside of it.
Make sure that the socket.io.js in the version 2.2 (same as the CDN version). You can get this file by downloading it directly from the CDN URL you were using or using npm -i -s socket.io-client#2.2. You can then find the socket.io.js file in node_modules/socket.io-client/dist.
You now just need to use <script src="/static/socket.io.js"></script> in your HTML to import socket.io.

nodejs config on subdirectory

I have a sub-domain and I publish my server.js on this directory. everything work fine. but I want to running my server.js inside a directory(because I want to run my react.js project on sub directory). for example:
web.example.com/sr
web is my subdomain and sr is my directory.
but my routes not worked at all:
web.example.com/sr/user/1
I got this error message:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /sr/user/1</pre>
</body>
</html>
Should I make any changes or is there any config to do this?
You can't do deployment-level configs to serve your react app to the subdir /sr. Every call to your.domain.com/sr/* will end up in your server and pass /sr/* to it (and not simply /*.
You'll have to code your server to serve your React app. If you bundle your react app to index.html and bundle.js, you'll have to write something like this (if you're using express, which you probably do):
app.get(/\/sr\/\.js/, (req, res) => res.sendFile(`${__dirname}/bundle.js`));
app.get(/\/sr\/*/, (req, res) => res.sendFile(`${__dirname}/index.html`));
If you're using react-router, you'll have to set it up too so as to take into account the leading /sr in your URL.

Using s3, node js

i'm trying to make a http request using 'request' for nodeJS. But it doesn't work.
It keeps writing 'require is not defined'. I have uploaded my index.html file to my s3 bucket, as well as my node_modules folder and my package.json file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.20/browser.min.js"></script>
<script data-main="js.config" src="js/r.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
const request = require('request');
</script>
This is how the index.html file looks like. It's not the whole file. But it's only the 'require' part is making trouble..
Let me know if you need any more info.
Hope someone can help.
You cannot use the request package on a client side script in that way, pointed out by many of the comments posted. That being said, if you want to have an App with a Node JS Backend for the serverside, you probably shouldn't be using AWS S3 anyways. There are many options for you if you plan to make a Backend App with Node JS:
AWS EC2 with Node JS
AWS Lambda
AWS Elastic Beanstalk
Some of these options, notably the EC2 and Lambda, have free tier options. Hopefully this helps you.

Categories

Resources