I'm incorporating service workers into my meteor app; everything works fine on desktop browsers so I'm trying to test it out on mobiles.
So the app is running on localhost and I'm running ngrok so I can access on my phone. When the code tries to install the service worker, I get the following error:
SecurityError: Failed to register a ServiceWorker: the origin of the provided scriptURL (localhost:3000) does not match the current origin (https://abc123.ngrok.io)
Is there any way around this so I can play with service workers on my phone during development?
(Here is my setup in case it makes a difference - it's pretty standard)
try {
navigator.serviceWorker.register(Meteor.absoluteUrl('sw.js')).then((registration) => {
return registration.pushManager.getSubscription()
.then((subscription) => {
if(subscription) {
return subscription;
}
const reg = registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicKey)
});
return reg;
})
.then((subscription) => {
savePushRegistration.call({ pushSubscription: JSON.stringify(subscription) });
});
})
.catch((error) => {
console.info('Can\'t load SW', error); //This is where the error appears
});
} catch (e) {
// We're good here
// Just an old browser
}
});
I run HTTPS web servers on my laptop that my devices can connect to if they're on the same WiFi network. I configure custom CNAMEs with short TTL (5 minutes) for my domain and provide my laptop's IPs for them. My laptop server listens for those hostnames:
https://laptop-home.example.com
https://laptop-work.example.com
https://laptop-secret-lair.example.com
Getting HTTPs running locally on your computer is beyond the scope of this question, but you should create your own self-signed certificates using a custom CA Root certificate that you can install and trust on your phone. Then, you'll avoid SSL warnings when browsing to all of your self-signed sites.
A little more work than using a remote server, but well worth it if you want to avoid outside servers.
Related
I had watched a series of tutorials online and had followed lot of steps. I had to change my IP address to my machine IP, but yet network error. even, I had to change it to 127.0.0.1. Am just so tired, I need help badly. I am using a project on the PHPMyAdmin database, which I use to fetch the result using express and node MySQL. I did all I could I even used USB tethering, hotspot, and all but none seems to work
const GetUserData =()=>{
axios.get("http://127.0.0.1:3000/users").then(
(response)=>{
console.log(response.data);
}).catch(err =>{
console.log(err);
})
};
useEffect(() => {
GetUserData()
},[])
Can you add the error message, please? If you face CORS you can fix it by:
var cors = require('cors')
var app = express()
app.use(cors())
Your machine has multiple IP addresses, even with one network device.
Of them:
127.0.0.1 - local IP address. It is not on any network device, and it should not be there.
192.168.x.y - network IP address. It is configured on the network device (manually or automatically).
You don't need to install 127.0.0.1 on a network device. 127.0.0.1 is already your machine, even without any network devices.
Also, to be able to make requests to 127.0.0.1:3000, some service must already listen on this port.
Java server, javascript client, no special libraries, plain text HTTP/1.1 and websocket connections.
Server side written (in Eclipse) using JDK 16 and a websocket jar found in Tomcat, version 10.0.2. (Many permutations of other JDKs and websocket jars have also been tried.)
Two web applications. Tomcat 10.0.2 on PC, 10.0.7 on server. Both apps run on Windows 10. Deployed to a Ubuntu 20.04 server. Both programs display the initial HTTP data. One program gets a websocket connection and works, the other fails to get the websocket connection. Both use the same code to calculate the target URL for the websocket connection:
window.onload = function() {
var target = "ws://" + location.host + "/[context]/[endpoint]";
console.log("target: " + target);
try {
if ('WebSocket' in window) {
socket = new WebSocket(target);
} else if ('MozWebSocket' in window) {
socket = new MozWebSocket(target);
} else {
alert('WebSocket is not supported by this browser.');
return;
}
} catch (e) {
console.log("websocket connection exception: " + e.description);
}
...
Where only [context] and [endpoint] differ. Recall that these URLs work on a PC. I believe they are “well-formed”/valid.
Results for the web app that fails:
Firefox:
uncaught exception: Could not establish connection. Receiving end does not exist.
GET ws://35.xxx.xx.xx:8080/Memory/MemoryEndpoint[HTTP/1.1 404 70ms]
Firefox can’t establish a connection to the server at ws://35.xxx.xx.xx:8080/Memory/MemoryEndpoint.
Chrome:
Error handling response: TypeError: Cannot read property 'encrypt' of undefined
at Object.13 (chrome-extension://bkdgflcldnnnapblkhphbgpggdiikppg/public/js/content-scripts/autofill.js:1427:33)
. . .
game.js:31 WebSocket connection to 'ws://xxx.xx.xx.xx:8080/Memory/MemoryEndpoint' failed:
Chrome continues for many lines regarding the 'encrypt' undefined issue. I have no idea what that is about but it might be very relevant. The last line above implies that some reason for the failure might be given on the next line, but it is empty.
Neither browser logs the expected exception text beginning with: "websocket connection exception:".
Tomcat log files are all clean except for some curious entries in localhost__access_log such as:
209.90.225.218 - - [11/Jul/2021:00:43:33 +0000] "HEAD /robots.txt HTTP/1.0" 404 -
And others mentioning /invoker/readonly, /login, /jenkins/login, /nifi/.
The fact that both programs do return results from the Tomcat server tells me that permissions on ports etc are all sufficient. I've also dug into netstat results and the like, reviewed firewall settings, read many many articles and requests for help. (Probably irrelevant because Tomcat does return expected HTTP/1.1 data.) No luck.
I need this program to work. I would pay a cash reward for a solution to this by 07-16-2021, though I don't know how to discretely negotiate that. :-(
Problem resolved, though I don't understand the cause. Recall: the web application ran fine on development PC deployed to Tomcat version 10.0.2, for various JDKs, websocket libraries (including one found in the Tomcat 10.0.7 that had been installed on the VM). The app failed on the Ubuntu VM. A friend installed Tomcat 10.0.8 in the VM. Presto! websockets work.
I have a React and ASP.NET Core 2.2 SPA that has a CORS issue with Firefox but is okay in Chrome and Edge. I've created a little test rig that consists of the ASP.NET Core 2.2 Web API template with CORS enabled and a Create React App that uses fetch to call the web API.
Here's the ASP.NET Core Startup.cs with CORS enabled:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
builder.AllowAnyMethod().AllowAnyHeader().AllowCredentials().WithOrigins("http://localhost:3000");
}));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("CorsPolicy");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
Here's the React page that requests the data:
const App: React.FC = () => {
const [data, setData] = useState("loading ...")
useEffect(()=>{
fetch("https://localhost:44335/api/values").then(res=>res.json()).then(body=>{
setData(JSON.stringify(body));
})
},[]);
return <p>{data}</p>
}
This works fine in Chrome and Edge but I get the following error in Firefox:
Am I enabling CORS correctly? or am I missing something else? Any help appreciated.
On FireFox, the protocols must match for CORS policy origins. If your WebAPI has app.UseHttpsRedirection(); configured and your react app is being served from non SSL, you will get a CORS block. So either:
Disable app.UseHttpsRedirection(); in dev/local environment
Host your dev/local react app with SSL
Turn of SSL in iis express for the WebAPI
I know this question is old but I faced the same problem right now and my solution was not mentioned above.
Currently Firefox is very restrictive with self-signed development SSL certificates. So if you run both API and SPA frontend in SSL mode:
Make sure both are opened in Firefox and add exceptions for both developer certificates!
In my case I had the API only opened in Chrome and so the exception was still missing in Firefox. Hence the SSL-connection failed.
Just to add another facet to this...
I had a case where Firefox would give me a CORS error when calling a specific controller, but would work fine on other controllers in the same WebAPI instance.
What I found was on the 'problem' controller, it was actually throwing an exception. The exception in this case it was a 'Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException'. When I fixed the problem, the CORS errors went away. Probably other server-level exceptions would cause the same thing.
Who knows why FF would interpret an exception as a CORS error...
So I'm using localtunnel to expose my ports over the internet, but I only want to let devices on the same network as the server access the server.
I'm using express-ip-filter to filter away anything that's on a different network. I tried a few things: first I tried using 192.168.1.0/24 as the only ips that could access the website, but that didn't work, as it didn't let anything in. I then tried using the ip I got from WhatsMyIp, but that wouldn't let any device in. I then found out that express-ip-filter spits out a message saying that a certain ip was not allowed and, on every device, independently on the network it was connected to, the address was 127.0.0.1. I tried confirming by only allowing 127.0.0.1, and then every device could access the server. Why would ip-filter only get 127.0.0.1 as ip? Here's my code as a reference:
// Init dependencies
var express = require('express'),
ipfilter = require('express-ipfilter').IpFilter
app = express()
// Blacklist the following IPs
var ips = ['192.168.1.0/24']
// Create the server
app.use(ipfilter(ips, { mode: "allow" }))
app.get('/', function (req, res) {
res.send('Hi')
})
app.listen(8080, () => console.log('Up'))
From my limited understanding of localtunnel it seems like it proxies users requests to you via the localtunnel software which causes all users to have the same IP. In laymans terms:
User connects to your site through localtunnel
localtunnel copies the users request and sends it to your computer
Your application receives the request but it looks like all traffic is coming from localtunnel because it's incredibly difficult if not impossible for localtunnel to imitate someone else's IP.
Why use localtunnel at all if you only want devices on the same network to connect, you don't need to do any port forwarding or DNS setup if you just want to access another machine on the same local network.
If you really do need to tunnel connections then there is a solution, not with localtunnel(Which as far as i can tell does not use forwading headers, although if someone knows if they do ill change my answer) but using https://ngrok.com instead which does exactly the same thing but also sends a little extra bit of data in every request which tells the application what the clients actual IP is.
Install ngrok
Run ngrok http -subdomain=(the subdomain you want) 80
Edit your application code to find the real client IP
var findProxyIP = function(req) {
var realIP = req.header('x-forwarded-for');
return realIP;
}
app.use(ipfilter(ips, {
mode: "allow",
detectIP: findProxyIP
}));
ngrok is much more complex and has a lot more features compared to localtunnel, however, it is freemium software and its free plan is quite limiting.
I managed to configure a simple websocket server according to this tutorial in AWS EC2 instance and its working fine.
But only from my home internet connection which has a real IP and told as a dedicated internet line.
I tried with a very simple javascript example code from client side (using a HTML page) and it works perfectly if I use that dedicated internet connection from my PC/Mac. (I used autobahn.min.js) above the following script.
var conn = new ab.Session('ws://X.X.X.X:8080',
function() {
console.log("Connection established!");
// To Do: Subscribe with client ID
},
function() {
console.warn('Connection closed!');
},
{'skipSubprotocolCheck': false}
);
but it fails if I run the same simple file/script from under another shared internet connection such as cellular data or something like that. I get the following error in browser console.
WebSocket connection to 'ws://X.X.X.X:8080/ws' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT example.com Connection closed!
The server is in AWS EC2 instance. Yes, 8080 is enabled under security group. Actually all works fine except client connection goes from some specific types of internet connection based computer.
Thanks in advance for any help!