I'm new to Web Development (including JavaScript and HTML) and have a few issues within my personal project that seem to have no clear fixes.
Overview
My project is taking input from a user on the website, and feeding it to my back-end to output a list of word completion suggestions.
For example, input => "bass", then the program would suggest "bassist", "bassa", "bassalia", "bassalian", "bassalan", etc. as possible completions for the pattern "bass" (these are words extracted from an English dictionary text file).
The backend - running on Node JS libraries
trie.js file:
/* code for the trie not fully shown */
var Deque = require("collections/deque"); // to be used somewhere
function add_word_to_trie(word) { ... }
function get_words_matching_pattern(pattern, number_to_get = DEFAULT_FETCH) { ... }
// read in words from English dictionary
var file = require('fs');
const DICTIONARY = 'somefile.txt';
function preprocess() {
file.readFileSync(DICTIONARY, 'utf-8')
.split('\n')
.forEach( (item) => {
add_word_to_trie(item.replace(/\r?\n|\r/g, ""));
});
}
preprocess();
module.exports = get_words_matching_trie;
The frontend
An HTML script that renders the visuals for the website, as well as getting input from the user and passing it onto the backend script for getting possible suggestions. It looks something like this:
index.html script:
<!DOCTYPE HTML>
<html>
<!-- code for formatting website and headers not shown -->
<body>
<script src = "./trie.js">
function get_predicted_text() {
const autofill_options = get_words_matching_pattern(input.value);
/* add the first suggestion we get from the autofill options to the user's input
arbitrary, because I couldn't get this to actually work. Actual version of
autofill would be more sophisticated. */
document.querySelector("input").value += autofill_options[0];
}
</script>
<input placeholder="Enter text..." oninput="get_predicted_text()">
<!-- I get a runtime error here saying that get_predicted_text is not defined -->
</body>
</html>
Errors I get
Firstly, I get the obvious error of 'require()' being undefined on the client-side. This, I fix using browserify.
Secondly, there is the issue of 'fs' not existing on the client-side, for being a node.js module. I have tried running the trie.js file using node and treating it with some server-side code:
function respond_to_user_input() {
fs.readFile('./index.html', null, (err, html) => {
if (err) throw err;
http.createServer( (request, response) => {
response.write(html);
response.end();
}).listen(PORT);
});
respond_to_user_input();
}
With this, I'm not exactly sure how to edit document elements, such as changing input.value in index.html, or calling the oninput event listener within the input field. Also, my CSS formatting script is not called if I invoke the HTML file through node trie.js command in terminal.
This leaves me with the question: is it even possible to run index.html directly (through Google Chrome) and have it use node JS modules when it calls the trie.js script? Can the server-side code I described above with the HTTP module, how can I fix the issues of invoking my external CSS script (which my HTML file sends an href to) and accessing document.querySelector("input") to edit my input field?
Related
My main goal here is to execute a python script I have written when I run a function triggered through HTML. Here is how I have things currently set up:
I have a JavaScript File containing python run functions:
const PythonShell = require('python-shell').PythonShell;
class AHK {
static async runScript() {
PythonShell.run('/ahk/script.py', null, function (err) {
if (err) throw err;
console.log('finished');
});
}
module.exports = AHK;
I have my main.js file which would be the js code for the HTML to handle. I'd like for it to take in the module AHK. Something simple like this:
const AHK = require('./ahk');
function runFunction(x){
if(x = 1)
AHK.runScript()
}
And then I have some HTML with a javascript tag
<script type="text/javascript">
let x =1; //this is just to show x is getting populated. In the actual code it's constantly changing values
async function predict() {
if(x > 1)
runFunction(x)
}
</script>
Biggest issue I'm facing:
I've become aware that browser javascript doesn't like requirements/modules. For example, the main.js file doesn't like having a requirement at the top. I've tried using things like requirejs, but I can't seem to figure out how to make something like this work. I basically need it so that when the requirement is met and the function runFunction is run, the python script is executed on my machine.
Important to note that this is all running for a personal project on my computer, so it will never not be local.
Make the application on your pc an API and use the web page to send a request to the API telling it which python script to run. I haven't used python too much but I believe you can make an API with it. Then you can just make buttons for each python program you want to run and have these buttons send a request to the API.
I built a basic HTML & Javascript app to translate a few words from the Google Translate API then text them to a number via Twilio. Here is my HTML:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src="script.js"></script>
</head>
<body>
<p>Click the button to receive 3 Hebrew texts</p>
<input id="clickMe" type="button" value="clickme" onclick="myFunction();" />
</body>
</html>
And here is script.js:
function myFunction(){
// Imports the Google Cloud client library
const {Translate} =require('#google-cloud/translate').v2;
// Creates a client in Google API
const projectId = 'Xx'
const keyFilename = '/Users/x/Downloads/vocal-lead-306923-b3d8f6749397.json'
const translate = new Translate({projectId, keyFilename});
const lang = "he"
// Creates a client in Twilio API
const accountSid = 'Xx'
const authToken = 'Xx'
const client = require('twilio')(accountSid,authToken);
/** Set variables for input in Google API */
const text = ['One day'];
const target = lang;
async function translateText() {
// Translates the text into the target language. "text" can be a string for
// translating a single piece of text, or an array of strings for translating
// multiple texts.
let [translations] = await translate.translate(text, target);
translations = Array.isArray(translations) ? translations : [translations];
//console.log('Translations:');
translations.forEach((translation, i) => {
setTimeout(() => {
// Sends messages via Twilio
client.messages.create({
to:'+phone',
from:'+phone',
body: `${translation}`
})
}, i * 10000);
});
}
translateText();
}
myFunction();
By itself, the script works but it doesn't work when I run it from my local browser. I hit inspect and I get this error:
Uncaught ReferenceError: require is not defined
at myFunction (script.js:5)
at HTMLInputElement.onclick (index.html:8)
I took out auth keys/any personal data but I think that is all correct. Any advice would be helpful!
If you're trying to run the script in browser, it won't work. This is because require() is a nodejs feature, and so anything that depends on libraries by require needs to be done in a nodejs backend (you can communicate between html frontend and nodejs backend over http for example; see https://expressjs.com/ and https://nodejs.org/en/ the latter has builtin http but for routing express is recommended).
You mention that you've removed private information for this SO post, but keep in mind that when you publish this site and the script.js is visible to the user (i.e. inspect element) it'll be freely accessible. It is not good practice to put secrets in the frontend code. Consider this: a bad actor uses your API key to send spam SMS on your behalf... not good.
Also see: How to use google translation api with react
I'm new to ExpressJs. I have a question about posted javascript
app.get('/nothing/:code',function(req, res) {
var code = req.params.code;
res.send(code)
});
If I POST javascript tag, It would run. Is there way to prevent that?
There are many possible HTML sanitizers out there (as simple search on NPM will give you a listing that you can use in your nodejs code).
The most simple would be to simply use the built in "escape" function, but that won't stop many XSS attacks.
app.get('/nothing/:code',function(req, res) {
var code = escape(req.params.code);
res.send(code)
});
A better solution would be to use a library designed for this purpose. For example if you used the santizier library (Google Caja's HTML sanitizer packaged for node):
var sanitizer = require('sanitizer');
...
app.get('/nothing/:code',function(req, res) {
var code = sanitizer.sanitize(req.params.code);
res.send(code)
});
I'm struggling with an encoding-problem in a small system I'm constructing.
In an HTML, this script is loaded
<script src="http://localhost:8000/serving/dk-711218"></script>
and normally I can't access the HTML so everything has to be done inside the javascript file.
The server-side scripts are made in Node.js and it returns pieces of code depending on some settings in customizable XML files. For instance, when displaying an image the system returns a simple
<img src="mypicture.jpg" />
and if it's a text, it returns
<div class="myClass">This is a test</div>
and if they have special behaviors, this code is included as well.
These parts work as intended. These chunks of code resides inside a number of classes and are returned as needed so that the code is gradually built.
So far, so good.
The problem is returning the SWFobject library code, because it seems to corrupt the code on the fly.
All code has been escaped and encoded with encodeURIComponent so that the system just needs to decode and unescape. But the validation fails.
Here's an example of the first few lines before encoding/escaping:
var%2520swfobject%253Dfunction%2528%2529%257Bvar...
Here's how a piece of the SWFObject looks like in the Firefox source code window when accessing the page:
and here's how a piece of the decoded SWFObject looks like in the same window:
This occurs at several places and something that's common for these occurrences is that it looks like the less-than character for unknown reasons is interpreted differently.
Here's the view renderer and I can't figure out if problem is caused in the code or when rendering the code.
Any ideas to what's causing this behavior? Or perhaps some advices on best practice when including code this way?
Responses to comments:
try JSON.stringify
I've tried the JSON solution out as well and it does the trick!
What I did was - as before - to pre-process the included code, using a little tool I built with two input-fields and a JSON.stringify-command between the two. This resulted in the content of returnvar:
Module.prototype.opens = function () {
var returnvar = "var swfobject=function(){var D=\"undefined\",r=\"object\",S=\"Shockwave Flash\",W=\"ShockwaveFlash.ShockwaveFlash\",q=\"application/x-shockwave-flash\",R=\"SWFObjectExprInst\"... etc.
and a JSON.parse is used to correct it again in the renderer:
router.get('/serving/:id', function (req, res) {
var readSymbolicsXMLCallback = function(data) {
res.render('index', {
id: req.params.id,
embedcode: JSON.parse(data)
});
}
var embedcode = readSymbolicsXML(req.params.id, readSymbolicsXMLCallback);
});
I would like to save the results calculated on html page in a textfile using javascript.
<script type="text/javascript">
window.onload = function () {
var sw : StreamWriter = new StreamWriter("HTML_Results.txt");
sr.Write('xyz");
*** calculations ******
sr.Write (result);
}
</script>
by doing this, my WP8 App is misbehaving and not displaying images as usual. This app is an Image Fader (calculates FPS).
Also tried:
StreamWriter sr;
try {
sr = new StreamWriter("\HTML5\HTMLResults.txt");
sr.Write("xyz");
File.SetAttributes("HTML5\HTMLResults.txt", FileAttributes.Hidden);
} catch(IOException ex) {
console.write ("error writing"); //handling IO
}
The aim is to:
Extract calculated values of several html pages(after getting loaded
one by one) in a single text file.
A Resultant HTML that reads this
text file and displays results in a tabular format.
Is there a better way to this job or the above can be rectified and used? Appreciate help.
Perhaps I've misunderstood your code but it looks like you're trying to write Java within JavaScript scripting tags. You cannot write Java in an HTML document. As far as I know, client-side JavaScript (which given your <script> tags is I guess what you're trying to write) can't perform the kind of file I/O operations you seem to want here.
You need to use Node JS to use JavaScript for something like that and then you're talking server-side. The closest you can get on client-side is using the new localStorage feature in HTML5 (not supported by all browsers).