Communicating between browser and local application - Secure connection? - javascript

Currently creating an application launcher and updater based on a web page. Knowing the limitations of browsers (security reasons), for my project I needed to have a local application to control the update and the creation of the OS process.
While testing and researching for a good amount of time; Now I have a working local-app, written in Go, that can create a process and kill it from an ajax POST request. I prepared some code to show, how my current attempt looks like (nothing fancy) :
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>api_test</title>
<script src="js/jquery-3.0.0.min.js"></script>
<script src="js/script.js"></script>
</head>
<body>
<h2 id="statusText"></h2>
</body>
</html>
js/script.js
$(document).ready(function(){
console.log("Hey! ;)");
tryConnection();
});
function tryConnection() {
var statusReq = $.ajax({
method: "GET",
url: "http://127.0.0.1:9091/api/test",
dataType: "json"
});
statusReq.fail(function(){
$('#statusText').text("Fail");
setTimeout(tryConnection, 5000);
});
statusReq.done(function(json){
$('#statusText').text(json.status);
console.log("Integer result: " + json.result);
setTimeout(tryConnection, 10000);
});
}
Local application, app.go
package main
import (
"log"
"net/http"
"encoding/json"
)
type APITest struct {
Status string `json:"status"`
Result int `json:"result,omitempty"`
};
func testHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*");
TestValue := APITest{Status: "Works!", Result: 123};
json.NewEncoder(w).Encode(&TestValue);
}
func main() {
log.Println("Started!");
http.HandleFunc("/api/test", testHandler);
err := http.ListenAndServe("127.0.0.1:9091", nil);
if err != nil {
log.Fatal("Error occured:", err);
}
}
Everything seems to be fine! But..
The only problem I currently can't figure out is, How can I actually add support for https:// connections without the need to carry the compiled binary with a cert and key file? Because I want to implement this feature into a https:// only website and mixing together https and http connections, results in a blocked mixed content error from browser security restrictions, which is understandable.
Maybe there are some other ways to implement this kind of communication? (to be clear, for WebSockets a secure connection is needed too).

Related

Why does fetching a gzipped file not work in localhost (with Javascript)?

I am utterly confused by gzipping ...
Situation:
I have a json-file with 2mb that I'd like to gzip.
It should work on the basic, cheap FTP server that my client has/uses
The file basically never changes, so I'd like to pre-gzip it and don't do it dynamically (also regarding 2.)
At first I thought I need a library like Pako, but then I read that it is supported natively by browsers.
I tried it with the following example:
example.json
{
"this-is-a": "simple-json"
}
example.json.gz (created with zlib)
1f8b 0800 0000 0000 0013 abe6 5200 02a5
928c cc62 5d20 4a54 b252 502a cecc 2dc8
49d5 cd2a cecf 53e2 aa05 00f2 869a 6022
0000 00
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<script>
fetchGzippedData('./example.json.gz')
function fetchGzippedData(url){
fetch(url).then(function (response) {
return response.json()
})
.then(function (json) {
console.log(json);
})
.catch(function(err) {
console.error('Error loading file')
});
}
</script>
</body>
</html>
Result
The weird thing is it doesn't work on localhost (using serve or with Astro preview).
It also doesn't work on my personal server, but it does work on my client's server.
So I assume it has to do with server configuration (which I have no experience with) ... but why doesn't it work in localhost?
Related:
Gzipped javascript not being served properly
Referenced GZipped JavaScript files not working
Ok, I finally figured it out.
It fails because the the .gz-file's Response Header Content-Encoding is wrong or missing.
(This information can be viewed for the respective file in the Network-tab in the browser's debug tools.)
It has to be set to Content-Encoding : gzip
Once it's correct it can fetch and parse the json-file as it wasn't gzipped.
For the static site server serve I am using you can set options via a serve.json:
(But I also saw similar information for Apache)
{
"headers": [
{
"source" : "**/*.#(gz|gzip)",
"headers" : [{
"key" : "Content-Encoding",
"value" : "gzip"
}]
}
]
}
Side note: I noticed, that if you access the .gz-file via the browser directly:
If Content-Encoding is correct: The browser shows the file content
If Content-Encoding is not correct: The browser will download the file

Java Plug In support in browser to be depricated.. Alternative solution for an Applet to access Client File System?

We are having a web application which is developed in Oracle ADF.
1) From the doc page Download and Open Folder button , We are using the applet to download files to a location in client machine and opens the folder
2) From the doc page Download and Open Files button , We are using the applet to download files to a location in client machine and open those files
3) From the doc page Open Folder Button, Which will open the corresponding doc folder if exist.
The above 3 points already exist and its working perfectly.
Now since plugin support will be removed from browsers. We are looking for an alternative solution.
Any suggestions would help us.. Please advise
Regards
Arun
To replace the java aplet, you can use a local service that implements a restful interface.
Launch local service with a simple GET request to jnlp file. For example, http://example.com/localservice.jnlp This will download, install, and run the local service (the requirements for it are as applet - it must be signed). Once the local service has been successfully launched, the web application can submit and read data from it, just as it would with any web server.
However, it should be kept in mind that browsers do not allow cross-queries. Therefore, either a CORS header from the local service should be returned or the address that it listens to (127.0.0.1) should be part of the application domain (this is done by subdomain with A record for 127.0.0.1 for example localhost.example.com)
Here's an example conversion (pretty rough)
This is the local service that listens on port 8888 for incoming HTTP queries and returns a JSON response.
public class LocalService {
public LocalService() {
}
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress("localhost", 8888), 0);
server.setExecutor(Executors.newSingleThreadExecutor());
server.createContext("/", httpExchange -> {
StringBuilder builder = new StringBuilder();
int read;
byte buffer[] = new byte[1024];
InputStream is = httpExchange.getRequestBody();
while ((read = is.read(buffer)) != -1) {
builder.append(new String(buffer, 0, read));
}
is.close();
String response = String.format("{\"request\": \"%s\"}", builder.toString());
Headers headers = httpExchange.getResponseHeaders();
headers.add("Content-Type", "application/json");
headers.add("Access-Control-Allow-Origin", "*");
httpExchange.sendResponseHeaders(200, response.length());
OutputStream os = httpExchange.getResponseBody();
os.write(response.getBytes());
os.flush();
os.close();
});
server.start();
}
}
This is the JNLP file used to start the service.
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="" href="">
<information>
<title>Local Service</title>
</information>
<resources>
<!-- Application Resources -->
<jar href="http://example.com/localservice.jar" main="true" />
</resources>
<security>
<all-permissions/>
</security>
<application-desc name="Local Service" main-class="LocalService">
</application-desc>
<update check="background"/>
</jnlp>
And this is an HTML page that starts automatically or manually the service and sends and receives data from it
<!DOCTYPE html>
<html>
<head>
<title>Local Service</title>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script>
$(function() {
$('#send').click(function() {
$.ajax({
method: 'POST',
url: 'http://localhost:8888', // or localhost.example.com:8888
data: $('#data').val(),
success: function(data, textStatus, jqXHR) {
alert(data.request);
},
error: function(jqXHR, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
});
</script>
</head>
<body>
<h1>Local Service</h1>
<!-- auto load local service -->
<iframe style="display: none;" src="localservice.jnlp"></iframe>
Run Local Service Manually
<div style="margin-top: 50px;">
<input id="data"/>
<button id="send">Send</button>
</div>
</body>
</html>

SignalR inside an iframe not receiving

My web application that utilizes signalR sent from an API hub works well on all browsers. Now, when I try to add the link of my web application inside an iframe within a basic html page, my web application does not execute my connection methods.
Here a snippet of my code in my web application:
$.connection.hub.url = 'myUrl';
$.connection.hub.logging = true;
var varHub= $.connection.MyHub;
$.connection.hub.start()
.done(function () { console.log("Signal R connected"); //this is being executed })
.fail(function () { console.log("Could not Connect to signal R hub!"); });
$.connection.hub.disconnected(function () {
setTimeout(function () {
$.connection.hub.start();
}, 5000); // Re-start connection after 5 seconds
});
//Methods to be called by the server for signal R connections
varHub.client.start= function () {
//this is not being called
//do something
};
As I have said I have no problems when I directly access it via url. The issue only happens when I try to insert the url in an iframe.
Here's how I do it:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="X-UA-Compatible" content="IE=11">
</head>
<body width="1280" height="736" style="margin:0;padding:0;overflow:hidden;border:0px;background:#000000;">
<iframe
src="http://myUrl/Home/Index?Id=someId" style="width:1280px;height:720px;margin:0;paddin:0;overflow:hidden;border:0px;"/>
scrolling="no"/>
</body>
</html>
Note: My target browser is IE 11.
Any ideas will be a great help! Thanks.
For anyone who will might encounter this in the future, this parameter fixed my issue.
Source: Here
Negotiating a transport takes a certain amount of time and client/server resources. If the client capabilities are known, then a transport can be specified when the client connection is started. The following code snippet demonstrates starting a connection using the Ajax Long Polling transport, as would be used if it was known that the client did not support any other protocol:
$.connection.hub.start({ transport: 'longPolling' })

NodeJS to Client : large data sending performance

How can I send large data from NodeJS to Client?
I tried this two:
1. Socket.io request
2. Ajax GET request
But both way are slow.
I am using mongoDB. Data size would be 1,000,000+ objects(1-2GB) but even 10,000 data sending, It is so slow.
How can I make it more faster? (Data reading time from MongoDB to NodeJS is no problem. )
This is Socket.io code
=> NodeJS
io.sockets.on('connection', function(socket) {
socket.on('getData', function() {
var items = TestModel.find();
items.find({},function(err,obj){
for(var i=0;i<obj.length;i++){
socket.emit('responseData', obj[i]);
}
socket.emit('complete',"Item length : ");
});
});
});});
If I use socket.emit('responseData', obj), I ll get a overflow err
=> index.HTML
<html>
<head>
<meta charset="utf-8"/>
<script src="/socket.io/socket.io.js"></script>
<title></title>
</head>
<body>
Socket.io Test
</body>
<script>
window.onload = function() {
var socket = io.connect();
socket.emit('getData');
var i=0;
//socket.emit('getName');
socket.on('responseData', function(data) {
i++;
});
socket.on('complete',function(data){
alert(data+i);
});
};
</script>
</html>
This is Ajax GET code
=> NodeJS
app.get('/load',function(req,res){
var items = TestModel.find();
console.log("Model loaded");
items.find({},function(err, obj){
res.send(JSON.stringify(obj));
console.log("Sent Models");
});
});
=> Ajax
$(function(){
$(document).ready(function(){
$.get('/load', {}, function(data){
...
});
});});
compression
Check and/or enable compression, you could get up to 10x gain, depending on data and format. There's a tradeoff between compression quality and server cpu usage, in general, start with best compression algorithm browser (or client) supports.
If the client is under your control, you could even try xz or something more exotic :)
caching
Tag your responses (https://en.wikipedia.org/wiki/HTTP_ETag) and add hooks for If-None-Match: ... request header field.
streaming
Depends on what the client is using the data for, is it saved? processed? displayed? In many cases client can start performing actions on part of data. If that part is at the start of response, streaming it makes a lot of sense
parallelize
Clients could use Range: ... request header field to download segments of data. In which case single client could issue multiple requests against segments of given dataset simultaneously. This typically helps if client's network is crappy (e.g. another continent).
preview
Perhaps client can process or "show" a simplified representation of data first. If there's a human user behind the client, they may wish to quickly check your data before making a decision to download it. Pretty common for images and design documents where a thumbnail or preview is generated server-side.

XMLHttpRequest cannot load http://ideone.com/api/1/service.wsdl. Origin null is not allowed by Access-Control-Allow-Origin.

XMLHttpRequest cannot load http://ideone.com/api/1/service.wsdl. Origin null is not allowed by Access-Control-Allow-Origin.
please help me in this regard
<html>
<head>
<title> Web services </title>
<script type="text/javascript" src="jquery.js">
</script>
<script type="text/javascript" src="soapproxy.js">
</script>
<script type="text/javascript">
testob={user:"harisrinivas",pass:"ideonehari"};
function resultcallback(res, xml, text, proxy) {
alert(res);
}
function failurecallback(res, xml, text, proxy) {
alert("SayHello() failed");
}
function gotproxycallback(proxy, wsdl, text) {
if (proxy instanceof SOAPProxy) {
//proxy.SayHello(null, true, resultcallback, failurecallback);
SOAPProxy.prototype.invoke(test, testob, async, resultcallback, faultcallback);
} else {
alert("Proxy not created!");
}
}
$(document).ready(function () {
try {
SOAPProxyFabric.fromUrl("http://ideone.com/api/1/service.wsdl", true, gotproxycallback);
} catch (x) {
alert("Failed to load or parse WSDL!");
}
});
</script>
</head>
<body>
<h1> Web service testing by Hari Srinivas </h1>
</body>
</html>
i'm using jquery and soapproxy (http://code.google.com/p/js-soap-proxy/). What is the problem ? and how can i remove this error..??
I guess soapproxy fromurl uses xmlhttprequest, a page from website A is not allowed to make a request to website B. where:
A = google.com
B = yahoo.com
or
A = mysite:80.com
B = mysite:90.com
or
A = subdomain.mysite.com
B = othersub.mysite.com
You can find same origin policy information on wikipedia. A way to go around it is JSONP but I don't think soapproxy uses it. Another way to quickly find out if this is your problem is get the forcecors plugin for firefox, activate it (view -> toolbars -> add on bar) click on cors (right bottom of the screen). If it's red you can connect from any site to any site because the plugin fiddles with the http response making it pretend that server B has send you the cors header (allowing other websites to connect to it with xmlhttprequests).
If you have access to the server that has the service on it, you can enable cors easily on the server by following directions on this site: http://enable-cors.org/ , they have examples for each type of webserver.

Categories