I have an asp.net application, where I need to add a script in the section of my html, and a value in that script needs to change based on the environment (TEST, QA etc..). For simplicity lets just say this is my script, where DisplayValue is the value that needs to be dynamic:
<head>
<script>
alert("Hello World! Value='" + DisplayValue + "'");
</script>
</head>
This is an asp.net application, but there is no corresponding .aspx file, just plain old html. Is it possible to read the value from the web.config? Some other way I haven't thought of?
My solution was to create a separate script file for each environment. Then, based off the url of the page, determine which environment I am running in and dynamically load the correct script.
<script>
function loadJS(url, async = true) {
let scriptElement = document.createElement("script");
scriptElement.setAttribute("src", url);
scriptElement.setAttribute("type", "text/javascript");
scriptElement.setAttribute("async", async);
document.head.appendChild(scriptElement);
//success
scriptElement.addEventListener("load", () => {
console.log("Script file loaded.")
});
//error
scriptElement.addEventListener("error", (ev) => {
console.log("Error loading script file", ev);
});
}
var url = window.location.href.toUpperCase();
if (url.indexOf("WWWQA.") >= 0) {
//Load script for QA environment
loadJS("Scripts/QA-SCRIPT.js", true);
}
else if (url.indexOf("WWW.") >= 0) {
//Load script for PROD environment
loadJS("Scripts/PROD-SCRIPT.js", true);
}
</script>
Related
I found interesting code on stack overflow, but the only thing I don't like about it is that it uses JQuery that is imported via the Internet, and I need it all to work without connecting to the Internet. Can you please tell me how this can be changed?
Code:
void handleRoot() {
snprintf ( htmlResponse, 3000,
"<!DOCTYPE html>\
<html lang=\"en\">\
<head>\
<meta charset=\"utf-8\">\
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\
</head>\
<body>\
<h1>Time</h1>\
<input type='text' name='date_hh' id='date_hh' size=2 autofocus> hh \
<div>\
<br><button id=\"save_button\">Save</button>\
</div>\
<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\
<script>\
var hh;\
$('#save_button').click(function(e){\
e.preventDefault();\
hh = $('#date_hh').val();\
$.get('/save?hh=' + hh , function(data){\
console.log(data);\
});\
});\
</script>\
</body>\
</html>");
server.send ( 200, "text/html", htmlResponse );
}
void handleSave() {
if (server.arg("hh")!= ""){
Serial.println("Hours: " + server.arg("hh"));
}
}
void setup() {
// Start serial
Serial.begin(115200);
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
server.on ( "/", handleRoot );
server.on ("/save", handleSave);
server.begin();
}
void loop() {
server.handleClient();
}
The minified jquery javascript can be stored on the ESP and served up by the module when the browser requests it.
One easy way to do this is to use the SPI Flash File System to serve up the HTML as well as the JQuery javascript.
This means creating an index.html in a data sub-directory in the sketch. Add the HTML in the original sketch into the file. Also change the script source in this file to a relative path:
<script src="jquery.min.js"></script>
Then download jquery.min.js and copy this into the data sub-directory as well.
The example code at https://tttapa.github.io/ESP8266/Chap11%20-%20SPIFFS.html can be used as a starting point for the rest of the code. The main parts of this involve initializing SPIFFS and setting up the handler for the file request:
SPIFFS.begin();
server.onNotFound([]() {
if (!handleFileRead(server.uri()))
server.send(404, "text/plain", "404: Not Found");
});
// retain the save endpoint
server.on("/save", handleSave);
server.begin();
Then implement the file handler and its content type handler:
String getContentType(String filename)
{
if (filename.endsWith(".html")) return "text/html";
else if (filename.endsWith(".css")) return "text/css";
else if (filename.endsWith(".js")) return "application/javascript";
else if (filename.endsWith(".ico")) return "image/x-icon";
return "text/plain";
}
bool handleFileRead(String path) {
Serial.println("handleFileRead: " + path);
if (path.endsWith("/"))
{
path += "index.html";
}
String contentType = getContentType(path);
if (SPIFFS.exists(path))
{
File file = SPIFFS.open(path, "r");
size_t sent = server.streamFile(file, contentType);
file.close();
return true;
}
Serial.println("\tFile Not Found");
return false;
}
Alternate Approach: Remove the JQuery dependency
An alternative approach is to rewrite the javascript so that JQuery is not required.
This involves registering an onclick handler on the button (https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers), getting the value from the input field (https://stackoverflow.com/a/11563667/1373856) and sending a GET request (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
You just has to include it as script-tag with the local path on your machine.
<script src="path-to-jquery/jquery.min.js" type="text/javascript"></script>
Edit: First you have to download the needed jquery file and store it in your local path. The needed path-to-jquery should than be a relative path from the html-file to the jquery.
My problem is that I have a JavaScript function written in a PHP file and when I call it from AJAX request, I want to run that JavaScript function on the main page too after successful AJAX request. As an example, I have a main.html file where I have written an AJAXX function as below.
main.html
<script type="text/javascript">
/* AJAX Function
----------------------------------------------- */
function ajaxFunction() {
var FD = new FormData();
var ajx = new XMLHttpRequest();
ajx.onreadystatechange = function () {
if (ajx.readyState == 4 && ajx.status == 200) {
document.getElementById("mainContent").innerHTML = ajx.responseText;
hello(); //Uncaught ReferenceError: hello is not defined
}
};
ajx.open("POST", "/example.php", true);
ajx.send(FD);
document.getElementById("mainContent").innerHTML = 'Loading...';
return false;
}
</script>
And my example.php file contains a JavaScript function as
example.php
<?php
echo 'Some contents and functions';
echo '<script type="text/javascript">
function hello() {
alert("Hello");
}
</script>';
echo 'Some contents and functions';
?>
Now when I run index.html file, I get Uncaught ReferenceError: hello is not defined error in console rest I am seeing the function body is written on HTML page while inspecting elements on-page.
As I know that innerHTML does not run scripts. So what's the workaround to this problem. You can view the below-linked answer also that I think is related to my question but tried and not working with my problem.
Researched Questions/Answers:
https://stackoverflow.com/a/3250386/3170029
https://stackoverflow.com/a/47614491/3170029
As I shared and you know that innerHTML does not run scripts. so we have to look around it then I found a solution on StackOverflow and I am sharing here with this problem's answer.
main.html
<script type="text/javascript">
/* AJAX Function
----------------------------------------------- */
function ajaxFunction() {
var FD = new FormData();
var ajx = new XMLHttpRequest();
ajx.onreadystatechange = function () {
if (ajx.readyState == 4 && ajx.status == 200) {
setInnerHTML(document.getElementById("mainContent"), ajx.responseText); // does run <script> tags in HTML
hello();
}
};
ajx.open("POST", "/example.php", true);
ajx.send(FD);
document.getElementById("mainContent").innerHTML = 'Loading...';
return false;
}
//https://stackoverflow.com/a/47614491/3170029
var setInnerHTML = function(elm, html) {
elm.innerHTML = html;
Array.from(elm.querySelectorAll("script")).forEach(oldScript => {
const newScript = document.createElement("script");
Array.from(oldScript.attributes)
.forEach(attr => newScript.setAttribute(attr.name, attr.value));
newScript.appendChild(document.createTextNode(oldScript.innerHTML));
oldScript.parentNode.replaceChild(newScript, oldScript);
});
}
</script>
Its concept is clear. When you get the response data from PHP file then first extract <script ..... </script> tags from it and add them in index.html file hear by using createElement('script') and copy all the script to this then you can easily call your function after response data anywhere.
In other words, You can create an executing script element outside of that initial parse using the DOM method of calling createElement('script'), setting its src/content, and adding it to the document. The alternative is what jQuery's getScript90 does.
I'm trying to add \node_modules\sip.js\dist\sip.min.js , to my html file. I tried to import like import * as SIP from 'sip.js/dist/sip'; in my component.ts but this work only if I call some function from it. But I need my html file to read this sip.min.js.
Also I tried to download local this files and added in my html file
<script src="js/sip-0.5.0.js"></script>
<script src="js/ua.js"></script>
and added:
public loadScript() {
console.log("preparing to load...");
let node = document.createElement('script');
node.src = this.url;
node.type = "text/javascript";
node.async = true;
node.charset = "utf-8";
document.getElementsByTagName("head")[0].appendChild(node);
}
ngOnInit() {
this.loadAPI = new Promise(resolve => {
console.log("resolving promise...");
this.loadScript();
});
}
But this is not working
You could add them to body. Also your paths should be available from client side. But adding scripts in Init event is bad practice - it is added each time as component is created. I have added scripts in service - it executes once.
const files = ['js/sip-0.5.0.js','js/ua.js']
files.forEach((file) => {
const fileRef = document.createElement('script');
fileRef.setAttribute('type', 'text/javascript');
fileRef.setAttribute('src', file);
fileRef.onload = function () {
console.log('loaded' + file);
};
document.body.appendChild(fileRef);
});
But this approach is good only for dynamic adding scripts based on some condition. If your scripts are independent from other files you could just add it to bundle file without any manually struggling.
I want to put a text file into a javascript function and then somehow display that function in the html.
The javascript can't be inside the html file; it has to be referenced from outside the file like a:
Here is a picture of what I am trying to do (I don't have enough rep points):
https://i.ibb.co/xGxw1bm/1.png
I have tried:
I tried using "XMLHttpRequest" to try and display the text file in the front end html by uploading my text file to dropbox so I can be using the "https" method to communicated instead of "file://" since that doesn't work in the twitch developer rig
const Http = new XMLHttpRequest();
const url=' https://cors-anywhere.herokuapp.com/https://app.box.com/s/zkt7pbsv0cnnogafcxq8n5elmc9plxbz';
\\later in the code; because I didn't know where to put the rest of the http commands so I put them in the twitch.onAuthorized function which needs to be ran in this script anyway. I don't know what it does but it needs to be there and since its already a function I figured it would be better there. (Unless someone can make a function where all the https stuff is in one function.)
twitch.onAuthorized(function (auth) {
// save our credentials
token = auth.token;
tuid = auth.userId;
Http.open("GET", url);
Http.send();
Http.onreadystatechange=(e)=>{
console.log(Http.responseText);
setAuth(token);
$.ajax(requests.get)
}
});
I tried the document.getelement thingy but that doesn't ever explain to me how to put this in the html as text:
document.getElementById("demo").innerHTML
Everything I have seen on this has always said you can manipulate using a tag but I have not seen one example where this document.get thingy is in another javascript file and they have to reference it to the html. I always see it in the same file with the html.
What function can I use to extract that function into the html file without using a button? I just want it to display on like an object tag or an iframe tag.
I tried using the object tag....
It seems to work however......
I notice it pulls the website like an html file. Is there anyway to direct link a text file to the object tag but just the text data shows? Do I have to upload my text to a secure https? Can I even pull a text file from the web without it pulling in the html?
Here is the html file exact: (Note: This is testing, so none of the words matter in the html file. I am just trying to learn how to put text on here from another javascript file or backend.js javascript file. What tag or reference can I use to put a function from javascript into here without a button? Just on the screen I need the text.:
<!DOCTYPE html>
<html>
<head>
<title>Viewer Page</title>
</head>
<body style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">
<div id="app" class="full-height"></div>
<script src="twitch-ext.min.js"></script>
<script src="jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="viewer.js" type="text/javascript"></script>
<h2>Hello, World!</h2>
<p>Would you care to cycle a color?</p>
<object type="text/html" data="https://www.w3.org/TR/PNG/iso_8859-1.txt"></object>
</body>
</html>
Here is the viwer.js (this is where the javascript for getting the text file needs to be):
const Http = new XMLHttpRequest();
const url=' https://cors-anywhere.herokuapp.com/https://app.box.com/s/zkt7pbsv0cnnogafcxq8n5elmc9plxbz';
let token = '';
let tuid = '';
const twitch = window.Twitch.ext;
// create the request options for our Twitch API calls
const requests = {
set: createRequest('POST', 'output'),
};
function createRequest (type, method) {
return {
type: type,
url: location.protocol + '//localhost:8081/musicoutput/' + method,
success: updateBlock,
error: logError
};
}
function setAuth (token) {
Object.keys(requests).forEach((req) => {
twitch.rig.log('Setting auth headers');
requests[req].headers = { 'Authorization': 'Bearer ' + token };
});
}
twitch.onContext(function (context) {
twitch.rig.log(context);
});
twitch.onAuthorized(function (auth) {
// save our credentials
token = auth.token;
tuid = auth.userId;
Http.open("GET", url);
Http.send();
Http.onreadystatechange=(e)=>{
console.log(Http.responseText);
setAuth(token);
$.ajax(requests.get)
}
});
function updateBlock (hex) {
twitch.rig.log('Updating music info');
}
function logError(_, error, status) {
twitch.rig.log('EBS request returned '+status+' ('+error+')');
}
function logSuccess(hex, status) {
twitch.rig.log('EBS request returned '+hex+' ('+status+')');
}
I have a type of SPA which consumes an API in order to fetch data. There are some instance of this SPA and all of them use common style and script files. So my problem is when I change a single line in those files, I will have to open each and every instances and update the files. It's really time consuming for me.
One of the approaches is to put those files in a folder in the server, then change the version based on the time, but I will lose browser cache if I use this solution:
<link href="myserver.co/static/main.css?ver=1892471298" rel="stylesheet" />
<script src="myserver.co/static/script.js?ver=1892471298"></script>
The ver value is produced based on time and I cannot use browser cache. I need a solution to update these files from the API, then all of the SPAs will be updated.
In your head tag, you can add the code below:
<script type="text/javascript">
var xmlhttp = new XMLHttpRequest();
var url = "http://localhost:4000/getLatestVersion"; //api path to get the latest version
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var tags = JSON.parse(xmlhttp.responseText);
for (var i = 0; i < tags.length; i++) {
var tag = document.createElement(tags[i].tag);
if (tags[i].tag === 'link') {
tag.rel = tags[i].rel;
tag.href = tags[i].url;
} else {
tag.src = tags[i].url;
}
document.head.appendChild(tag);
}
}
};
xmlhttp.open("POST", url, false);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send();
</script>
Your api path should allow "CORS" from your website that handles the code above.
And your api should return a json data like below:
var latestVersion = '1892471298'; //this can be stored in the database
var jsonData = [
{
tag: 'link',
rel: 'stylesheet',
url: 'http://myserver.co/static/main.css?ver=' + latestVersion
},
{
tag: 'script',
rel: '',
url: 'http://myserver.co/static/script.js?ver=' + latestVersion
}
];
//return jsonData to the client here
If you change anything in your JS or CSS then you have to update the browser cache, all you can do is to update that particular JS version not all of them, it should reflect in browser.
How about adding a method in your API returning the files' last modified time and then inserting the value into the "src"/"href" attribute after the "ver="