I am making some java project about non-using browser service.
So, I want to use some JavaScript function from server (which is a callback from my POST)
I saw many codes about using JavaScript in java, but it's from local files.
I think one solution about this:
When callback is coming, save this code and use it again. But I think it's not optimal for our project.
Can you give me any other solution?
Thank you in advance.
Yes, you can, as #Daniel Baranowski suggested above.
And no, you absolutely shouldn't.
Running any code submitted by the client is putting yourself in an extreme risk.
Can it access your filesystem? Then you're in trouble.
Can it execute network calls? Then you're also in trouble.
And even if you blocked those options, do you check that this user code terminates in time?
It is certainly possible but it can expose you to huge security risks.
Nothing is stopping you from running JavaScript code directly from a String. Having it saved in a file is not a requirement. You can get the body of the POST which was send do your server and execute it somewhat like this:
package example;
import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Example {
private final ThreadLocal<NashornScriptEngine> engineHolder;
public Example() {
// You don't need to run code from files. The code can be a string which was posted to your server.
String jsCodeToRun = "function helloWorld(name) { return { value: 'Hello' + name } }"
this.engineHolder = ThreadLocal.withInitial(() -> {
NashornScriptEngine nashornScriptEngine = (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn");
try {
nashornScriptEngine.eval(jsCodeToRun);
} catch (ScriptException e) {
throw new RuntimeException(e);
}
return nashornScriptEngine;
});
}
public JSObject runTheCode(String name) {
try {
JSObject result = (JSObject) engineHolder.get().invokeFunction("helloWorld", name);
// The result will be an object returned by our helloWorld function.
return result;
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
}
Related
I have java class which I'm doing file copy to another directory. I want to call it in javascript. I wrote something like this.
for(var i=0;i<arrayExtensions.length;i++){
if(arrayExtensions[i]==value.extType){
var x=new Package.org.solr.copyImages();
var y=x.main(value.FileName,value.FilePath);
document.getElementById(showImages).src=y;
$(this).find("#showImages").fadeIn();
}
else{
$(this).find("#showImages").fadeOut();
}
But when I run my project it gives me this error in console.
Uncaught ReferenceError: Package is not defined
at HTMLAnchorElement.<anonymous> (index.jsp:216)
at HTMLDocument.dispatch (jquery-1.12.4.js:5226)
at HTMLDocument.elemData.handle (jquery-1.12.4.js:4878)
My java codes like this
public static String main(String name,String path) {
// TODO Auto-generated method stub
File original=new File(path);
File dest=new File("T:\\Temp\\");
try {
FileUtils.copyFileToDirectory(original, dest);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String newPath="T:\\Temp\\"+name;
return newPath;
}
What am I doing wrong?
Java doesn't run in the web browser. When using Java and JavaScript together, typically you do an ajax request to the server, which runs the Java code and produces a result, which is then sent back to the browser to be processed by the JavaScript code that did the ajax request (specifically, its success handler).
The answers to this question may also be useful: What is the difference between client-side and server-side programming?
Windows won't let my WebView_ScriptNotify Event receive a call if the html is loaded from ms-appdata.
I'm aware that I can use the ms-appx-web protocol to load such a file from my app bundle, but this is no option because the data to show are downloaded after install of the app.
I also can't just use webView.navigateToString because this won't include the referenced libraries in the html file.
Currently I'm trying something like this in my Class.xaml.cs
WebView webView = new WebView();
webView.ScriptNotify += WebView_ScriptNotify;
Uri navigationUri = new Uri(#"ms-appdata:///local/index.html");
webView.Navigate(navigationUri);
and
private void WebView_ScriptNotify(object sender, NotifyEventArgs e)
{
System.Diagnostics.Debug.WriteLine("ScriptNotifyValue: " + e.Value);
//I want to do the magic here, but this will never be called
}
in the html file is
<div id="content">
<div class="btn" onClick="window.external.notify('hello world');"</div>
</div>
Furthermore, it's no option to use InvokeScript(), because I don't know when the event must be fired and the values for it.
Yet it's mandatory to use files from ms-appdata.
Do you know a solution for this?
Even an alternative workaroung would amaze me.
Ref Script notify changes in XAML:
For content to be able to send notifications the following conditions apply:
The source of the page should be from the local system via NavigateToString(), NavigateToStream() or ms-appx-web:///
Or
The source of the page is delivered via https:// and the site domain name is listed in the app content URI’s section of the package manifest.
So to solve this issue, we can use WebView.NavigateToLocalStreamUri method with the protocol ms-local-stream://, rather than ms-appdata://. For example:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// The 'Host' part of the URI for the ms-local-stream protocol needs to be a combination of the package name
// and an application-defined key, which identifies the specific resolver, in this case 'MyTag'.
Uri url = webView.BuildLocalStreamUri("MyTag", "index.html");
StreamUriWinRTResolver myResolver = new StreamUriWinRTResolver();
// Pass the resolver object to the navigate call.
webView.NavigateToLocalStreamUri(url, myResolver);
}
private void webView_ScriptNotify(object sender, NotifyEventArgs e)
{
System.Diagnostics.Debug.WriteLine("ScriptNotifyValue: " + e.Value);
}
}
public sealed class StreamUriWinRTResolver : IUriToStreamResolver
{
public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
{
if (uri == null)
{
throw new Exception();
}
string path = uri.AbsolutePath;
// Because of the signature of the this method, it can't use await, so we
// call into a seperate helper method that can use the C# await pattern.
return GetContent(path).AsAsyncOperation();
}
private async Task<IInputStream> GetContent(string path)
{
// We use app's local folder as the source
try
{
Uri localUri = new Uri("ms-appdata:///local" + path);
StorageFile f = await StorageFile.GetFileFromApplicationUriAsync(localUri);
IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
return stream;
}
catch (Exception) { throw new Exception("Invalid path"); }
}
}
For more info, please see Remarks and Examples in WebView.NavigateToLocalStreamUri method and also Custom URI resolving in What’s new in WebView in Windows 8.1. Besides, there is also a WebView control (XAML) sample on GitHub.
I am developing web application in Java, and I must print reports, when clicked on button, on client side printer. How to implement? How to show printers from client side???
I use:
PrintService[] printers =
PrintServiceLookup.lookupPrintServices(null, null);
But this is on server side.
As your requirement is not clear. I am not sure about what exactly you want but for print you can use this window.print()
function myFunction() {
window.print();
}
<p>Click To print.</p>
<button onclick="myFunction()">Click</button>
You can read more about this here(simple) and here(explained).
Edit:
And if you want to print a particulate element content you can use this function:
function myPrint(data)
{
var testPage = window.open('', 'Test Page', 'height=500,width=500');
testPage.document.write('<html><head><title>Test Page</title>');
testPage.document.write('</head><body >');
testPage.document.write(data);
testPage.document.write('</body></html>');
testPage.document.close();
testPage.focus();
testPage.print();
testPage.close();
return ;
}
You must use javascript on the client page.
window.print()
https://developer.mozilla.org/en-US/docs/Web/API/Window/print
If you want to try the applet approach give a look at this answer
You cannot do that for security reasons. If you could, applets would
already have become notorious for printing 10+ pages of 'special
offers' when you visit unscrupulous web sites.
OTOH, if the client is willing to accept one prompt at applet
start-up, you could digitally sign the code.
Also it should be possible to achieve a similar result using the PrintService from JNLP API without the need for a signed applet.
Like in the Following example
import javax.jnlp.*;
...
PrintService ps;
try {
ps = (PrintService)ServiceManager.lookup("javax.jnlp.PrintService");
} catch (UnavailableServiceException e) {
ps = null;
}
if (ps != null) {
try {
// get the default PageFormat
PageFormat pf = ps.getDefaultPage();
// ask the user to customize the PageFormat
PageFormat newPf = ps.showPageFormatDialog(pf);
// print the document with the PageFormat above
ps.print(new DocToPrint());
} catch (Exception e) {
e.printStackTrace();
}
}
// Code to construct the Printable Document
class DocToPrint implements Printable {
public int print(Graphics g, PageFormat pageformat, int PageIndex){
// code to generate what you want to print
}
}
I had implemented HttpHandler for Js extension for google api hosted jquery script files. because when it is called need to replace http with https. But visual studio started compiling javascript on pages being loaded. how do I suppress this behavior. And most interesting why did it happened.
My Http Handler :
public class HttpToHttpsHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
try
{
if (context.Request.RawUrl.Contains("http:"))
{
context.Response.ContentType = "text/plain";
string newUrl = context.Request.RawUrl.Replace("http", "https");
context.Server.Transfer(newUrl);
}
}
catch (Exception)
{
throw;
}
}
}
What possibly went wrong.
It is because you have used Server.Transfer() which doesn't issue redirect to the browser but changes the execution path on the server - in the result ASP.NET will try to create something out of your JavaScript.
You want to make a simple redirection so just use Response.Redirect()
context.Response.Redirect(newUrl, false);
Also I would like suggest a more safe approach for altering the URL (in case there would be port number in URL etc.):
if (!context.Request.IsSecureConnection)
{
UriBuilder secureUriBBuilder = new UriBuilder(context.Request.Url);
secureUriBBuilder.Scheme = Uri.UriSchemeHttps;
//Ude default port for schema - alter this if your server is using custom port for HTTPS
secureUriBBuilder.Port = -1;
context.Response.Redirect(secureUriBBuilder.Uri.ToString(), false);
}
Also remember that the entire page will remain in non-safe mode if you will load the HTML in HTTP and try to load only JavaScript through HTTPS - you should consider redirection in Global.asax or usage of URL Rewrite module.
I want to create an application where a web server can get the MAC Address of the clients logging in. The only possible way I could think of was to create a JAVA applet which contains java.net methods to find the mac address
I am using javascript to call the applet methods, but the browser is not allowing those methods to execute. Below is the applet I have created.
import java.applet.*;
import java.awt.*;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
public class AppletRunner extends Applet{
// The method that will be automatically called when the applet is started
public void init()
{
// It is required but does not need anything.
}
//This method gets called when the applet is terminated
//That's when the user goes to another page or exits the browser.
public void stop()
{
// no actions needed here now.
}
//The standard method that you have to use to paint things on screen
//This overrides the empty Applet method, you can't called it "display" for example.
public void paint(Graphics g)
{
//method to draw text on screen
// String first, then x and y coordinate.
g.drawString(getMacAddr(),20,20);
g.drawString("Hello World",20,40);
}
public String getMacAddr() {
String macAddr= "";
InetAddress addr;
try {
addr = InetAddress.getLocalHost();
System.out.println(addr.getHostAddress());
NetworkInterface dir = NetworkInterface.getByInetAddress(addr);
byte[] dirMac = dir.getHardwareAddress();
int count=0;
for (int b:dirMac){
if (b<0) b=256+b;
if (b==0) {
macAddr=macAddr.concat("00");
}
if (b>0){
int a=b/16;
if (a==10) macAddr=macAddr.concat("A");
else if (a==11) macAddr=macAddr.concat("B");
else if (a==12) macAddr=macAddr.concat("C");
else if (a==13) macAddr=macAddr.concat("D");
else if (a==14) macAddr=macAddr.concat("E");
else if (a==15) macAddr=macAddr.concat("F");
else macAddr=macAddr.concat(String.valueOf(a));
a = (b%16);
if (a==10) macAddr=macAddr.concat("A");
else if (a==11) macAddr=macAddr.concat("B");
else if (a==12) macAddr=macAddr.concat("C");
else if (a==13) macAddr=macAddr.concat("D");
else if (a==14) macAddr=macAddr.concat("E");
else if (a==15) macAddr=macAddr.concat("F");
else macAddr=macAddr.concat(String.valueOf(a));
}
if (count<dirMac.length-1)macAddr=macAddr.concat("-");
count++;
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
macAddr=e.getMessage();
} catch (SocketException e) {
// TODO Auto-generated catch block
macAddr = e.getMessage();
}
return macAddr;
}
}
Applets cannot normally access these functions for security reasons. To avoid these restrictions, you need a signed applet, along with a policy file.
You can then write a policy file which grants your applet access to the functionality it needs. If the user then grants your applet the necessary permissions (it will prompt for them), your applet can use the functions.
In Netbeans, you can sign an application enabling the WebStart:
Access to Your project > properties > Application > WebStart
Check "Enable Web Start". This show a sectin titled signing.
Click the "Customize" button located in the signing section.
Select "self-sign by generated key".
I don't think this will be possible. Web servers communicate with clients several layers above the link layer where MAC addresses live -- it's abstracted away by TCP/IP and there's no reason for the client to send it unless you specifically have client code to do that.
The reason your Java code isn't working is because the Java sandbox's security manager disallows such low-level calls -- which it should! If you ever do find a way to get that thing to work (which I doubt you will) you should promptly report it to Oracle because it shouldn't be happening at all.
I can't see much of a reason why you'd want it either, to be honest.
The Java applet is prevented to access those methods on the client because it runs in a protected sandbox.
It might not be possible within a browser, since it is against the sandboxing paradigm. You might have some luck with browser-specific native code extensions.
However, the important exception is if your web server is in the same local area network (same switch) as the client - then, the MAC address of the client is known to the server because it is still present in the IP packet.