-
Notifications
You must be signed in to change notification settings - Fork 32
sakshi-js-fetch-security-debugging-assignments #529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <title>Search Products</title> | ||
| <link rel="stylesheet" href="./styles/styles.css"> | ||
| </head> | ||
| <body> | ||
| <header> | ||
| <h1><a href="index.html">E-Shop</a></h1> | ||
| <nav> | ||
| <a href="index.html">Search</a> | ||
| <a href="list.html">All Products</a> | ||
| <a href="view.html">View Product</a> | ||
| </nav> | ||
| </header> | ||
|
|
||
| <main> | ||
| <h2>Search Products</h2> | ||
| <input type="text" id="searchInput" placeholder="Enter product name..."> | ||
| <button onclick="searchProducts()">Search</button> | ||
| <div id="results" class="grid"></div> | ||
| </main> | ||
|
|
||
| <script src="./scripts/script.js"></script> | ||
| </body> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,26 @@ | ||||||
| <!DOCTYPE html> | ||||||
| <html lang="en"> | ||||||
| <head> | ||||||
| <meta charset="UTF-8"> | ||||||
| <title>All Products</title> | ||||||
| <link rel="stylesheet" href="./styles/styles.css"> | ||||||
| </head> | ||||||
| <body> | ||||||
| <header> | ||||||
| <h1><a href="index.html">E-Shop</a></h1> | ||||||
| <nav> | ||||||
| <a href="index.html">Search</a> | ||||||
| <a href="list.html">All Products</a> | ||||||
| <a href="view.html">View Product</a> | ||||||
| </nav> | ||||||
| </header> | ||||||
|
|
||||||
| <main> | ||||||
| <h2>All Products</h2> | ||||||
| <button onclick="loadProducts()">Load Products</button> | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a best practice to avoid inline event handlers like In your const loadButton = document.getElementById('loadProductsButton');
if (loadButton) {
loadButton.addEventListener('click', loadProducts);
}
Suggested change
|
||||||
| <div id="products" class="grid"></div> | ||||||
| </main> | ||||||
|
|
||||||
| <script src="./scripts/script.js"></script> | ||||||
| </body> | ||||||
| </html> | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,60 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async function searchProducts() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const query = document.getElementById("searchInput").value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const resultsDiv = document.getElementById("results") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resultsDiv.innerHTML = "Loading..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const res = await fetch(`https://dummyjson.com/products/search?q=${query}`) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When including user input in a URL, it's important to properly encode it to handle special characters (e.g.,
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!res.ok) throw new Error("Failed to fetch products") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const data = await res.json() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resultsDiv.innerHTML = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data.products.forEach(p => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resultsDiv.innerHTML += ` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="product-card"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <img src="${p.thumbnail}" alt="${p.title}"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <h3>${p.title}</h3> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p>$${p.price}</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div>` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+9
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using
A much safer and more performant approach is to create DOM elements programmatically and set their content using
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (err) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resultsDiv.innerHTML = `<p style="color:red">${err.message}</p>` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Displaying raw error messages via
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async function loadProducts() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const productsDiv = document.getElementById("products") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| productsDiv.innerHTML = "Loading..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const res = await fetch("https://dummyjson.com/products?limit=12") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!res.ok) throw new Error("Failed to fetch products") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const data = await res.json() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| productsDiv.innerHTML = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data.products.forEach(p => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| productsDiv.innerHTML += ` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="product-card"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <img src="${p.thumbnail}" alt="${p.title}"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <h3>${p.title}</h3> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p>$${p.price}</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div>` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+30
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (err) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| productsDiv.innerHTML = `<p style="color:red">${err.message}</p>` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Displaying raw error messages via
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async function viewProduct() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const id = document.getElementById("productId").value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const detailsDiv = document.getElementById("productDetails") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| detailsDiv.innerHTML = "Loading..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const res = await fetch(`https://dummyjson.com/products/${id}`) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!res.ok) throw new Error("Product not found") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const p = await res.json() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| detailsDiv.innerHTML = ` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <img src="${p.thumbnail}" alt="${p.title}"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <h3>${p.title}</h3> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p><strong>Price:</strong> $${p.price}</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p>${p.description}</p>` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+52
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Directly setting detailsDivinnerHTML = '';
const img = document.createElement('img');
img.src = p.thumbnail;
img.alt = p.title;
const title = document.createElement('h3');
title.textContent = p.title;
const price = document.createElement('p');
const priceLabel = document.createElement('strong');
priceLabel.textContent = 'Price:';
price.append(priceLabel, ` $${p.price}`);
const description = document.createElement('p');
description.textContent = p.description;
detailsDiv.append(img, title, price, description); |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (err) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| detailsDiv.innerHTML = `<p style="color:red">${err.message}</p>` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Displaying raw error messages via
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| body { | ||
| font-family: Arial, sans-serif; | ||
| margin: 0; | ||
| background: #f5f5f5; | ||
| color: #333; | ||
| } | ||
|
|
||
| header { | ||
| background: #2c3e50; | ||
| color: white; | ||
| padding: 1rem 2rem; | ||
| display: flex; | ||
| justify-content: space-between; | ||
| align-items: center; | ||
| } | ||
|
|
||
| header h1 a { | ||
| margin: 0; | ||
| font-size: 1.8rem; | ||
| color: white; | ||
|
|
||
| } | ||
|
|
||
| nav a { | ||
| color: white; | ||
| margin-left: 1rem; | ||
| text-decoration: none; | ||
| font-weight: bold; | ||
| transition: color 0.3s; | ||
| } | ||
|
|
||
| nav a:hover { | ||
| color: #f39c12; | ||
| } | ||
|
|
||
| main { | ||
| padding: 2rem; | ||
| } | ||
|
|
||
| input, button { | ||
| padding: 0.6rem; | ||
| margin: 0.5rem 0; | ||
| border-radius: 5px; | ||
| border: 1px solid #ccc; | ||
| } | ||
|
|
||
| button { | ||
| background: #3498db; | ||
| color: white; | ||
| border: none; | ||
| cursor: pointer; | ||
| } | ||
|
|
||
| button:hover { | ||
| background: #2980b9; | ||
| } | ||
|
|
||
| .grid { | ||
| display: grid; | ||
| grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); | ||
| gap: 1.5rem; | ||
| margin-top: 1.5rem; | ||
| } | ||
|
|
||
| .product-card { | ||
| background: white; | ||
| border-radius: 10px; | ||
| padding: 1rem; | ||
| box-shadow: 0 4px 8px rgba(0,0,0,0.1); | ||
| text-align: center; | ||
| transition: transform 0.2s; | ||
| } | ||
|
|
||
| .product-card:hover { | ||
| transform: scale(1.05); | ||
| } | ||
|
|
||
| .product-card img { | ||
| max-width: 100%; | ||
| border-radius: 8px; | ||
| margin-bottom: 0.5rem; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,27 @@ | ||||||
| <!DOCTYPE html> | ||||||
| <html lang="en"> | ||||||
| <head> | ||||||
| <meta charset="UTF-8"> | ||||||
| <title>View Product</title> | ||||||
| <link rel="stylesheet" href="./styles/styles.css"> | ||||||
| </head> | ||||||
| <body> | ||||||
| <header> | ||||||
| <h1><a href="index.html">E-Shop</a></h1> | ||||||
| <nav> | ||||||
| <a href="index.html">Search</a> | ||||||
| <a href="list.html">All Products</a> | ||||||
| <a href="view.html">View Product</a> | ||||||
| </nav> | ||||||
| </header> | ||||||
|
|
||||||
| <main> | ||||||
| <h2>View Product by ID</h2> | ||||||
| <input type="number" id="productId" placeholder="Enter product ID"> | ||||||
| <button onclick="viewProduct()">View Product</button> | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a best practice to avoid inline event handlers like In your const viewButton = document.getElementById('viewProductButton');
if (viewButton) {
viewButton.addEventListener('click', viewProduct);
}
Suggested change
|
||||||
| <div id="productDetails" class="product-card"></div> | ||||||
| </main> | ||||||
|
|
||||||
| <script src="./scripts/script.js"></script> | ||||||
| </body> | ||||||
| </html> | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,15 @@ | ||||||
| <!DOCTYPE html> | ||||||
| <html lang="en"> | ||||||
| <head> | ||||||
| <meta charset="UTF-8" /> | ||||||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||||
| <title>HTML Assignments | Sakshi Bhosale</title> | ||||||
| </head> | ||||||
| <body> | ||||||
| <details> | ||||||
| <summary>Assignment 1</summary> | ||||||
| <iframe src="./assignment-1/index.html" frameborder="0" width="100%"></iframe> | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||
| </details> | ||||||
| </body> | ||||||
| </html> | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a best practice to avoid inline event handlers like
onclick. Instead, you should add event listeners in your JavaScript file. This helps to separate your HTML structure from your JavaScript logic, making the code cleaner and easier to maintain. You can add anidto the button to select it in your script.In your
script.js, you would then add something like this: