I have some code, and I'm hosting that with a live server along with a backend. It's a web-proxy that I'm currently working on, although I'm fairly new to networking and coding in general. In my code, if I type in something to the search engine, it'll filter it down to either /search or /url (express event listeners), but I'm having trouble displaying the response and visiting the actual websites (i.e. Youtube). The problem is that I can only load the basic HTML/CSS structure and not the actual videos, which I think I could solve using webSockets to create a stable connection. Slightly unrelated but here's my setup-
- My computer hosts the backend server and live server (I'll use ngrok tunneling later).
- When I'm at school, I'll use my iPad to connect to the live server.
- If I wanted to visit a website such as Youtube, the request would go thru the server to the backend and my computer would have a stable connection with Youtube as if my computer was the one who was requesting it, forwarding data back to the live server which would display whatever was searched up. Here's my code for reference (if it helps)- index.js:
let tabCount = 1;
function showTab(tabId) {
const tabs = document.querySelectorAll('.tab-content');
tabs.forEach(tab => {
tab.classList.remove('active');
});
document.getElementById(tabId).classList.add('active');
const tabElements = document.querySelectorAll('.tab');
tabElements.forEach(tab => {
tab.classList.remove('active');
});
event.target.classList.add('active');
}
function addNewTab() {
tabCount++;
const newTabId = `tab${tabCount}`;
const newTab = document.createElement('div');
newTab.className = 'tab';
newTab.textContent = `Tab ${tabCount}`;
newTab.setAttribute('onclick', `showTab('${newTabId}')`);
document.querySelector('.add-tab').before(newTab);
const newTabContent = document.createElement('div');
newTabContent.id = newTabId;
newTabContent.className = 'tab-content';
newTabContent.innerHTML = `
<img src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" alt="Google Logo" class="logo">
<div class="search-box">
<input type="text" id="${newTabId}-search-input" placeholder="Search Google or type a URL">
<button id="${newTabId}-search-btn">🔍</button>
</div>
<div class="buttons">
<button>Google Search</button>
<button>I'm Feeling Lucky</button>
</div>
<div id="${newTabId}-results" class="search-results">
<iframe id="${newTabId}-iframe" class="search-iframe" style="width: 100%; height: 80vh; display: none;" frameborder="0"></iframe>
</div>
`;
document.body.appendChild(newTabContent);
}
document.addEventListener("keydown", function (event) {
if (event.key === "Enter") {
const activeTab = document.querySelector('.tab-content.active');
const searchInput = activeTab.querySelector('input[type="text"]');
const inputValue = searchInput.value;
const isUrl = /^https?:\/\//i.test(inputValue);
const fetchUrl = isUrl ? `/urls?url=${encodeURIComponent(inputValue)}` : `/search?q=${encodeURIComponent(inputValue)}`;
fetch(fetchUrl)
.then((response) => response.text())
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error.message);
});
}
});
server.js:
const express = require('express');
const https = require('https');
const http = require('http');
const app = express();
const port = 5506;
app.use(express.static('public'));
const rewriteUrls = (html, baseUrl) => {
return html.replace(/(href|src)="([^"]*)"/g, (match, attr, url) => {
const absoluteUrl = new URL(url, baseUrl).toString();
return `${attr}="/proxy?url=${encodeURIComponent(absoluteUrl)}"`;
});
};
app.get('/search', (req, res) => {
const query = req.query.q;
const googleSearchUrl = `https://www.google.com/search?q=${encodeURIComponent(query)}`;
https.get(googleSearchUrl, (response) => {
let data = '';
response.on('data', chunk => {
data += chunk;
});
response.on('end', () => {
const rewrittenData = rewriteUrls(data, googleSearchUrl);
res.send(rewrittenData);
});
}).on('error', (err) => {
res.status(500).send('Error: ' + err.message);
});
});
app.get('/urls', (req, res) => {
let targetUrl = req.query.url;
const client = targetUrl.startsWith('https://') ? https : http;
client.get(targetUrl, (response) => {
let data = '';
response.on('data', (chunk) => {
console.log('Sending URL results back');
data += chunk;
});
response.on('end', () => {
res.send(data);
});
}).on('error', (err) => {
console.error('Error fetching URL:', err);
res.status(500).send('Error: ' + err.message);
});
});
app.get('/proxy', (req, res) => {
const resourceUrl = req.query.url;
https.get(resourceUrl, (response) => {
response.pipe(res);
}).on('error', (err) => {
res.status(500).send('Error: ' + err.message);
});
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thing</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f1f3f4;
}
.tabs {
display: flex;
justify-content: center;
align-items: center;
background-color: white;
border-bottom: 1px solid #ccc;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
padding: 10px 0;
position: sticky;
top: 0;
z-index: 10;
}
.tab {
padding: 10px 20px;
margin: 0 5px;
cursor: pointer;
font-size: 16px;
color: #5f6368;
border-bottom: 3px solid transparent;
transition: border-color 0.3s;
}
.tab:hover {
color: #202124;
}
.tab.active {
color: #1a73e8;
border-bottom: 3px solid #1a73e8;
}
.add-tab {
font-size: 24px;
font-weight: bold;
cursor: pointer;
color: #5f6368;
padding: 0 10px;
transition: color 0.3s;
}
.add-tab:hover {
color: #202124;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
text-align: center;
margin-top: 50px;
}
.logo {
margin: 20px auto;
}
.search-box {
margin: 20px auto;
width: 60%;
display: flex;
align-items: center;
border: 1px solid #dfe1e5;
border-radius: 24px;
background-color: white;
padding: 5px 15px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.search-box input {
flex: 1;
border: none;
outline: none;
font-size: 16px;
padding: 10px;
}
.search-box button {
background: none;
border: none;
cursor: pointer;
color: #5f6368;
font-size: 18px;
}
.buttons {
margin: 20px auto;
}
.buttons button {
margin: 5px;
padding: 10px 20px;
font-size: 14px;
color: white;
background-color: #1a73e8;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.buttons button:hover {
background-color: #1669c1;
}
</style>
</head>
<body>
<div class="tabs">
<div class="tab active" onclick="showTab('tab1')">Tab 1</div>
<div class="add-tab" onclick="addNewTab()">+</div>
</div>
<div id="tab1" class="tab-content active">
<img src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" alt="Google Logo" class="logo">
<div class="search-box">
<input type="text" placeholder="Search Google or type a URL">
<button>🔍</button>
</div>
<div class="buttons">
<button>Google Search</button>
<button>Random Button</button>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
If you've tried to host a live server on Visual Studio Code with this code, opened developer tools, typed something into the "search bar" and pressed enter, then a response from Google would appear into the console. Same thing works for URLs but they need to be in full (i.e. https://www.youtube.com). In conclusion, I just need help displaying the response and handling for webSockets which would allow for a stable connection between the backend server (my computer) and whatever website I'm visiting on my iPad. Sorry if I'm not clear enough (it's pretty late)! Thank you to anyone if they could help me!
Top comments (0)