I am trying to use the Have I Been Pwned? API to retrieve a list of breaches for a given email account.
I retrieve this list using the fetch() API. In the browser it looks like there is a connection to the HIBP website but the expected breaches are not visible.
I think this is a JSON problem because the API returns results without a root tree (?) (e.g. [breaches:{"Name"... - only the {"Name"}), so I think I'm making a mistake at the iteration step in the JS file. Also, I'm not calling the 'retrieve' function in the HTML file correctly because the browser throws an error: 'Uncaught ReferenceError: retrieve is not defined', but this is a side-issue (fetch('https://haveibeenpwned.com/api/v2/breachedaccount/test#example.com') doesn't work either).
This is my first week working with JS, fetch(), and JSON, so I consulted a couple of sources before asking this question (but I still can't figure it out, after a couple of days):
How to Use the JavaScript Fetch API to Get Data
fetch API
API methods for HaveIBeenPwnd.com (unofficial)
Where is the actual problem?
The index.html file:
<!DOCTYPE html>
<html lang=en>
<head>
<title>test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
</head>
<body id="top">
<header id="header">
<div class="content">
<h1 style="text-align: center">Put an email in this box</h1>
<input type="email" id="InputBox" value="" autocapitalize="off" spellcheck="false" />
<button type="submit" id="PwnedButton" onclick="retrieve">pwned?</button>
<ul id="results"></ul>
</div>
</header>
<script src="test.js"></script>
</body>
</html>
The test.js file (I know that JS is an interpreted language - so empty characters affect execution speed - but I made it more readable for this example):
function createNode(element) {
return document.createElement(element); // Create the type of element you pass in the parameters
}
function append(parent, el) {
return parent.appendChild(el); // Append the second parameter(element) to the first one
}
const account = document.getElementById('InputBox');
const PwnedButton = document.getElementById('PwnedButton');
const results = document.getElementById('results');
fetch('https://haveibeenpwned.com/api/v2/breachedaccount/' + account)
.then((resp) => resp.json()) // Transform the data into json
.then(function(retrieve) {
let breaches = retrieve.Name; // Get the results
return breaches.map(function(check) { // Map through the results and for each one run the code below
let span = createNode('span'); // Create the element we need (breach title)
span.innerHTML = `${breaches}`;
append(results, span);
})
})
.catch(function(error) {
console.log(JSON.stringify(error));
});
let breaches = retrieve.Name;
retrieve is not an object with a Name property.
It is an array containing multiple objects, each of which has a Name property.
You have to loop over it.
e.g.
retrieve.forEach( item => {
let breaches = retrieve.Name;
console.log(breaches);
});
breaches.map
… and the Name is a string, so you can't map it. You can only map an array (like the one you have in retrieve).
I have created working version of what are you possible going to implement, taking Name field from result. https://jsfiddle.net/vhnzm1fu/1/ Please notice:
return retrieve.forEach(function(check) {
let span = createNode('span');
span.innerHTML = `${check.Name}<br/>`;
append(results, span);
})
Related
I need a script that fetch id from javascript into an url
For example: https://google.com/youtube[id].mp3
javascript currently:
$(document).ready(function() {
// FETCHING DATA FROM JSON FILE
$.getJSON("https://api.omny.fm/orgs/56ccbbb7-0ff7-4482-9d99-a88800f49f6c/programs/a49c87f6-d567-4189-8692-a8e2009eaf86/clips/",function(data) {
$('#table').html(data.Clips[0].Id);
});
});
html currently:
<html lang="en"><head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./style.css">
</head>
<meta http-equiv="refresh" content="0; url=https://traffic.omny.fm/d/clips/56ccbbb7-0ff7-4482-9d99-a88800f49f6c/a49c87f6-d567-4189-8692-a8e2009eaf86/<p id="table">/audio.mp3" />
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="./script.js"></script>
</html>
i hope someone can help me out to get this working :)
thx.
tried multiple things to get id into url but not working
Your question is very unclear, but I assume what you're trying to do is fetch the JSON data, then append it to a table.
The first reason things aren't working is likely because your HTML is invalid. Specifically right here:
<!-- Why are you trying to embed a p tag into a link? -->
<meta http-equiv="refresh" content="0; url=https://traffic.omny.fm/d/clips/56ccbbb7-0ff7-4482-9d99-a88800f49f6c/a49c87f6-d567-4189-8692-a8e2009eaf86/<p id="table">/audio.mp3" />
The second issue is that you're using the jQuery .html() method, which actually just sets the innerHTML of an element. This is dangerous, and you should not do this (especially with fetched data).
// This is not good for many reasons
$('#table').html(data.Clips[0].Id);
Also, why are you using jQuery in 2023? DOM APIs are modern and extensive nowadays. jQuery is nothing but an abstraction on top of them. Here's a solution I believe will help you.
const URI = 'https://api.omny.fm/orgs/56ccbbb7-0ff7-4482-9d99-a88800f49f6c/programs/a49c87f6-d567-4189-8692-a8e2009eaf86/clips/';
const tableBody = document.querySelector('table > tbody');
const createCell = (content) => {
const cell = document.createElement('td');
cell.textContent = content;
return cell;
};
const createRow = (id, title) => {
const row = document.createElement('tr');
row.appendChild(createCell(id));
row.appendChild(createCell(title));
return row;
};
document.addEventListener('DOMContentLoaded', async () => {
// Use the native "fetch" API to fetch the data.
const res = await fetch(URI);
// Convert the data to JSON using the ".json()" method.
const json = await res.json();
// Loop through all of the clips in the received array.
for (const clip of json.Clips) {
// For each clip, add a new row to the table.
tableBody.appendChild(createRow(clip.Id, clip.Title));
}
});
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
</tr>
</thead>
<tbody></tbody>
</table>
I am trying to set up a simple search function with Google Books API. When I have my search parameter set as a simple preset string, it works fine. But when I attempt to make it take user input for the search parameter using document.getElementByID, it suddenly no longer works. I am uncertain of what could be going wrong,
<!DOCTYPE html>
<html>
<head>
<title>Google Books Search</title>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
</head>
<body>
<h1 id="title"></h1>
<h2>Searched "jquery"; Total results: <span id="total"></span>
<p>The results from 30 to 45 are displayed here (15 per page; results page #3).</p></h2>
<div id="results" style="display: flex; flex-wrap: wrap;"></div>
<input id="searchterm" type="text" placeholder="Search..." >
<button onclick="booksearch()">Search</button>
<script>
$(function booksearch(){
let term = "document.getElementById("searchterm").value;"
var parameter="?q="+term+"&startIndex=30&maxResults=15";
var service_point="https://www.googleapis.com/books/v1/volumes/"+parameter;
$.getJSON(service_point, function (json)
{
console.log(json);
var total=json.totalItems;
$("#total").text(total);
var resultHTML="";
for (i in json.items)
{
var booktitle=json.items[i].volumeInfo.title;
var bookid=json.items[i].id;
var cover="";
if (json.items[i].volumeInfo.imageLinks != null)
cover=json.items[i].volumeInfo.imageLinks.smallThumbnail;
resultHTML+="<div class='bookdiv'>";
resultHTML+="<img src='"+cover+"' style='float: left' />";
resultHTML+="<a href='bookinfo.html?id="+bookid+"'>"+booktitle+"</a>";
resultHTML+="</div>";
}
$("#results").html(resultHTML);
$(".bookdiv").css("width", "300px");
});
});
</script>
</body>
</html>
You should not put your "document.getElementById("searchterm").value;" within quotes otherwise it will just be a string.
Use let term = document.getElementById("searchterm").value; instead.
On another note: I would suggest you use fetch() together with URLSearchParams which will do the "heavy-lifting" (i.e. URL-encoding, addition of ? and & etc.) for you instead of concatenating those strings yourself (and you will use some modern JavaScript).
See this SO answer for an example.
Fairly basic question here. I've run into a situation where I can't seem to access Javascript functions from within my HTML file, even though I've linked the JS file as a script src. It seems like a pretty simple issue but I can't figure out what the problem is.
I'm trying to add a function called startLogin to an HTML button. I added it as an onclick, but then when I try to click the button, the console says the function is undefined. However the function is clearly defined in the JS file and as far as I can tell the syntax I'm using for the onclick and the script src link is correct.
In addition I've confirmed that the JS file is linked to the HTML file. If I try to manipulate the DOM from the JS file just to do something simple, like set the background to red, that works fine. The problem is when I try to call a function defined in the JS file. Also I've made sure the function I'm trying to call does actually work. If I stick it right in the HTML file inside script tags, it works fine.
I've already tried moving the script tags inside the body at the end of the HTML, as I know that's often the issue, but in this case it didn't work. Can anyone help me identify why I'm unable to access the "startLogin" function from the HTML button?
FYI, this is a javascript project and I'm using Vite.js for bundling. All the other HTML/JS files in my project are playing nicely together, I'm only having an issue with the Login page.
file structure:
|-pages
|-login.html
|-login.js
login.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>
<!-- LINK JS FILE -->
<!-- MODULE TYPE IS RELATED TO VITE.JS -->
<script type="module" src="./login.js"></script>
</head>
<body>
<!-- email login form -->
<form name="emailLogin" id="emailLogin" style="display: none">
<div class="row" style="width: 600px">
<div class="col">
<div class="form-row" style="padding-bottom: 10px">
<input
type="email"
class="form-control"
id="emailAddress"
placeholder="email associated with your login"
style="width: 576px"
/>
</div>
</div>
<div class="form-row">
<br />
<button type="button" class="btn btn-primary" onclick="startLogin('email')">
Send Email Login
</button>
</div>
</div>
</form>
</body>
</html>
login.js
// start the login process by generating a code sent either SMS or EMAIL
function startLogin(login_type) {
// local variables
var ajaxResult;
var subs;
var tempString;
// get the login values and set up the call
if (login_type == "phone") {
// get the values
use_country_code = $("#country").val();
use_phone = $("#phoneNumber").val();
use_phone = use_phone.replace(/\D/g, "");
// do the validation
if (use_phone.length < 10) {
$("#errorText").html(
"Phone number doesn't have enough digits, please try again."
);
$("#errorModal").modal("show");
return;
}
// build the url
post_url =
"https://us-central1-dev-api-327415.cloudfunctions.net/user-login?cc=" +
use_country_code +
"&phone=" +
use_phone;
} else {
// get the values
use_email = $("#emailAddress").val();
// do the validation
if (!validateEmail(use_email)) {
$("#errorText").html(
"Email address does not appear to be valid, please check the format and try again."
);
$("#errorModal").modal("show");
return;
}
// build the url
post_url =
"https://us-central1-dev-api-327415.cloudfunctions.net/user-login?email=" +
use_email;
}
// send the request to the server and process the results
$.LoadingOverlay("show");
$.ajax({
type: "POST",
url: post_url,
// process the returned result of the Ajax call
success: function (ajaxResult) {
// see if we have a session token and handle the response
session_token = ajaxResult["session_token"];
if (session_token == "None") {
// hide the login and show the text message area if phone, otherwise hide email and show email message
if (login_type == "phone") {
$("#loginMethod").hide();
$("#phoneLogin").hide();
$("#codeLogin").show();
$("#loginMessage").hide();
$("#textMessage").show();
} else {
$("#loginMethod").hide();
$("#emailLogin").hide();
$("#loginMessage").hide();
$("#codeLogin").show();
$("#emailMessage").show();
}
} else {
// hide everything since already logged in and show the right message
$("#phoneLogin").hide();
$("#emailLogin").hide();
$("#loginMethod").hide();
$("#loginMessage").hide();
$("#codeLogin").hide();
$("#continueLoginAlready").show();
}
},
// process after the Ajax call has been fully completed
complete: function () {
$.LoadingOverlay("hide");
},
// handle total failure
error: function (jqXHR, exception) {
console.log(jqXHR);
console.log(exception);
json_error = jqXHR["responseJSON"];
$("#errorText").html(json_error.error_message);
$("#errorModal").modal("show");
},
});
}
Javascript modules work a bit differently. There, variables and functions are not exposed to the global scope.
If you want to use your function from other parts of the code, you have to set it explicitly on the window object:
function startLogin(...) {
...
}
window.startLogin = startLogin;
an other solution is to set the js at end of the html, than you don't need to use the window object (memory lag)
<html lang="en">
<head>...</head>
<body>
<button type="button" id="myButton">Title</button>
</body>
<script>
function myFunction(){
console.log('running myFunction');
}
const button = document.querySelector('#myButton');
button.addEventListener('click', function clickListener(
{
myFunction();
}
</script>
</html>
the browser is simply stupid, it loads the page from top to bottom and if you load your js after the body all your html is present and you can do it this way.
I have created a simple login page with hardcoded username and password, I was successful in calling the next page once the login credentials are passed but I am having a tough time passing the user name entered in page 1 to appear on page 2.
I tried to find a way to make user inputs as global variables in js file so I can use the same variables in the second page but I am unsuccessful.
greeter.html
<body>
<h1>Simple Login Page</h1>
<form name="login">
Username<input type="text" name="userid"/>
Password<input type="password" name="pswrd"/>
<input type="button" onclick="check(this.form);" value="Login"/>
<input type="reset" value="Cancel"/>
</form>
<p id = "passwarn"></p>
<script language="javascript" src="source.js">
</script>
</body>
source.js
function check(form) { /*function to check userid & password*/
/*the following code checkes whether the entered userid and password are
matching*/
let uid = form.userid.value;
let pswrd = form.pswrd.value;
if(uid == "shiva" && pswrd == "mypswrd") {
window.open('test.html')/*opens the target page while Id & password
matches*/
}
else {
document.getElementById("passwarn").innerHTML = "User name or
password is incorrect!"/*displays error message*/
}
}
test.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>
<script language="javascript" src="source.js"></script>
<h1> Hello <span id = "UI"></span></h1>
</body>
</html>
I want Hello shiva printed on the test.html page, I do not want to use jquery while doing so, is there any way?
You can simply reference the value from the opening page in test.html.
To make things more straightforward, add an ID to the Username field :
Username <input type="text" name="userid" id="userid">
Then you can grab and display the value from the opened window like this :
<h1> Hello
<script>
document.write(window.opener.document.getElementById("userid").value)
</script>
</h1>
If you want to do things a little more elegantly, you could keep the scripting in your .js file and change the innerHTML of your "UI" span from there.
Bear in mind that cross-origin scripting rules mean that this will only work when served from the same domain.
Following on from the comments from your question two key points to identify
This is a very insecure way to do this
You may want to use cookies if the user if going to traverse many pages (not sponsoring, but I would recommend js-cookie, I have used it for a while and it's pretty robust)
In order to get what i believe you wanted to work i had to do a couple of this.
Put your JS on the page as for testing it quicker to have it all accessible on one page
I use function that is for parameter grabbing (yes this is completely insecure but would achieve what you want, a cookie would be more secure) you can find it here.
I renamed your inputs from names to ID's as they are more accessible in javascript this way.
This function when used with decode and encode URI components in javascript will help you pass the data from one page to another see code below
Greeter.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>
<h1>Simple Login Page</h1></script>
<form name="login">
Username<input type="text" id="userid"/>
Password<input type="password" id="pswrd"/>
<input type="button" value="Login" id="LoginSubmit"/>
<input type="reset" value="Cancel"/>
</form>
<p id = "passwarn"></p>
<script type="text/javascript" src="./source.js"></script>
</body>
</html>
then your test.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>
<h1> Hello <span id="UI"></span></h1>
<script type="text/javascript" src="./source.js"></script>
</body>
</html>
Finally your source.js
window.onload = checkpage(window.location.href);
function checkpage(url){
if(url.split('/').pop() == 'greeter.html'){
document.getElementById('LoginSubmit').addEventListener('click',function () {
var uid = document.getElementById('userid').value;
var pswrd = document.getElementById('pswrd').value;
console.log(uid, pswrd);
check(uid, pswrd);
});
}
else{
document.getElementById("UI").innerHTML = getAllUrlParams(decodeURIComponent(window.location.href)).uid;
}
}
function check(uid, pswrd) { /*function to check userid & password*/
/*the following code checkes whether the entered userid and password are
matching*/
let redirect = "test.html"
let parameters = encodeURIComponent('uid='+uid);
if(uid == "shiva" && pswrd == "mypswrd") {
window.open(redirect+"?"+parameters)/*opens the target page while Id & password
matches*/
}
else {
document.getElementById("passwarn").innerHTML = "User name or password is incorrect!"/*displays error message*/
}
}
function getAllUrlParams(url) {
// get query string from url (optional) or window
var queryString = url ? url.split('?')[1] : window.location.search.slice(1);
// we'll store the parameters here
var obj = {};
// if query string exists
if (queryString) {
// stuff after # is not part of query string, so get rid of it
queryString = queryString.split('#')[0];
// split our query string into its component parts
var arr = queryString.split('&');
for (var i = 0; i < arr.length; i++) {
// separate the keys and the values
var a = arr[i].split('=');
// set parameter name and value (use 'true' if empty)
var paramName = a[0];
var paramValue = typeof (a[1]) === 'undefined' ? true : a[1];
// (optional) keep case consistent
paramName = paramName.toLowerCase();
if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();
// if the paramName ends with square brackets, e.g. colors[] or colors[2]
if (paramName.match(/\[(\d+)?\]$/)) {
// create key if it doesn't exist
var key = paramName.replace(/\[(\d+)?\]/, '');
if (!obj[key]) obj[key] = [];
// if it's an indexed array e.g. colors[2]
if (paramName.match(/\[\d+\]$/)) {
// get the index value and add the entry at the appropriate position
var index = /\[(\d+)\]/.exec(paramName)[1];
obj[key][index] = paramValue;
} else {
// otherwise add the value to the end of the array
obj[key].push(paramValue);
}
} else {
// we're dealing with a string
if (!obj[paramName]) {
// if it doesn't exist, create property
obj[paramName] = paramValue;
} else if (obj[paramName] && typeof obj[paramName] === 'string'){
// if property does exist and it's a string, convert it to an array
obj[paramName] = [obj[paramName]];
obj[paramName].push(paramValue);
} else {
// otherwise add the property
obj[paramName].push(paramValue);
}
}
}
}
return obj;
}
So long as your HTML files are in the same folder you can run this. The main thing to notice is that you are binding the event listener to the element, getting the values input and then submitting them to the function.
I have added a function that retrieves the url of the page location and pops out the last bit of it and runs a check on it to ensure you are looking at the right place to run the correct code. as this runs on load then the subsequent functions run after. You can further refactor this to modularise it and ensure that it's cleaner to read if you wanted.
Splitting it out this way will make it easier when trying to implement a cookie as you can in the event listener (with a cookie created) can save those values to it on your greet page and then call them back after on your test page.
Hope that helps
Been trying to take specific data from an array of objects that for many reasons I cannot host on a server. The data is in stored as a variable in the document. This is what i've been trying so far to no success:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
var users = [{"username":"nphillips7m","first_name":"Nicole","last_name":"Phillips","email":"nphillips7m#ebay.co.uk","gender":"Female","sexuality":"Networked static concept","language":"Gagauz"},
{"username":"esimpson7n","first_name":"Elizabeth","last_name":"Simpson","gender":"Female","sexuality":"Future-proofed solution-oriented definition","language":"Malay"},
{"username":"llawrence7o","first_name":"Lillian","last_name":"Lawrence","email":"llawrence7o#technorati.com","gender":"Female","sexuality":"Re-contextualized demand-driven middleware","language":"Tetum"}]
var simpson = users.find("last_name" + "Simpson")
document.getElementById("return").innerHTML = function myfunction() {
simpson;
}
</script>
</head>
<body>
<div id="return"></div>
</body>
For now I've just been trying to extract some/any data from the 'users' array, but going forward i would like to have the user search for a word and the entire 'line'/'lines' of data related to the word/words in 'users' display as results. What methods should i use to achieve this?
You have some mistakes in your code. First of all, find function accept as argument a callback function.
var simpson = users.find(a=>a.last_name=="Simpson");
If you pass function to innerHTML, you must to invoke it, like this:
document.getElementById("return").innerHTML = (function myFunction(){
return JSON.stringify(simpson);
})();
and function must return a value in order to set the HTML content (inner HTML) of result element.
var users = [{"username":"nphillips7m","first_name":"Nicole","last_name":"Phillips","email":"nphillips7m#ebay.co.uk","gender":"Female","sexuality":"Networked static concept","language":"Gagauz"},
{"username":"esimpson7n","first_name":"Elizabeth","last_name":"Simpson","gender":"Female","sexuality":"Future-proofed solution-oriented definition","language":"Malay"},
{"username":"llawrence7o","first_name":"Lillian","last_name":"Lawrence","email":"llawrence7o#technorati.com","gender":"Female","sexuality":"Re-contextualized demand-driven middleware","language":"Tetum"}]
var simpson = users.find(callback);
function callback(item){
return item.last_name=="Simpson";
}
document.getElementById("return").innerHTML = (function myFunction(){
return JSON.stringify(simpson);
})();
<body>
<div id="return"></div>
</body>
1. You need to pass the callback function in find method. The find method searches for an element in an array and returns the element if it is found. Otherwise undefined is returned. The Search Criteria is defined by a callback function. Something like
var simpson = users.find(currentValue => currentValue.last_name === "Simpson");
2. You might not require your innerHTML to be a function, instead it would be more appropriate that it points to meaningfull information like UserName Found.
document.getElementById("return").innerHTML = simpson.username;
Try the following code.
var users = [{"username":"nphillips7m","first_name":"Nicole","last_name":"Phillips","email":"nphillips7m#ebay.co.uk","gender":"Female","sexuality":"Networked static concept","language":"Gagauz"},
{"username":"esimpson7n","first_name":"Elizabeth","last_name":"Simpson","gender":"Female","sexuality":"Future-proofed solution-oriented definition","language":"Malay"},
{"username":"llawrence7o","first_name":"Lillian","last_name":"Lawrence","email":"llawrence7o#technorati.com","gender":"Female","sexuality":"Re-contextualized demand-driven middleware","language":"Tetum"}]
var simpson = users.find(currentValue => currentValue.last_name === "Simpson");
document.getElementById("return").innerHTML = simpson.username;
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
</script>
</head>
<body>
<div id="return"></div>
</body>