I am using SockJS on my website and I am using the endpoint /msg
When I go to mysitename.com/msg/iframe.html, it shows this page:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script>
document.domain = document.domain;
_sockjs_onload = function(){SockJS.bootstrap_iframe();};
</script>
<script src="https://cdn.jsdelivr.net/sockjs/1.0.0/sockjs.min.js"></script>
</head>
<body>
<h2>Don't panic!</h2>
<p>This is a SockJS hidden iframe. It's used for cross domain magic.</p>
</body>
</html>
How does SockJS do this?
It's being sat within org.springframework.web.socket.sockjs.support.AbstractSockJsService from spring websocket at backend.
For example:
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
private static final String SOCKJS_VERSION = "https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.3.0/sockjs.min.js";
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/handler").setAllowedOrigins("*");
registry
.addEndpoint("/handler")
.setAllowedOrigins("*")
.withSockJS()
.setClientLibraryUrl(SOCKJS_VERSION);
}
}
If you follow setClientLibraryUrl, you'll se where it's being worked out.
Check https://github.com/spring-projects/spring-framework/blob/master/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java
and search for 'IFRAME_CONTENT'
Related
I have this javascript code that shows the current status of notification permission:
main.js
var $status = document.getElementById('status');
if ('Notification' in window) {
$status.innerText = Notification.permission;
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>Current permission status is
<b id="status">unavailable</b>
</p>
<script src="/scripts/main.js"></script>
</body>
</html>
If I write the same code in a typescript file I am getting this error:
main.ts
var $status = document.getElementById('status');
if ('Notification' in window) {
$status.innerText = Notification.permission;
}
ERROR - Notification.permission
MESSAGE - Property 'permission' not exists on type
'new(title: string, options?: NotificationOptions): Notification;
prototype: Notification;
requestPermission(callback?: NotificationPermissionCallback):
Promise<string>;'
How to ignore this error?
Try casting Notification to the any type to avoid transpiler errors.
if ('Notification' in window) {
$status.innerText = (Notification as any).permission;
}
The other option is to include the Notification type's definition.
I've read many posts but I can't get my Android app call a Javascript function. This is what I have
public class BorrameActivity extends AppCompatActivity {
private static BorrameActivity.MyJavaScriptInterface myJavaScriptInterface;
private static WebView webView;
public class MyJavaScriptInterface {
Context mContext;
MyJavaScriptInterface(Context c) {
mContext = c;
}
#android.webkit.JavascriptInterface
public void doEchoTest(String echo){
Log.e("printer", echo);
Toast toast = Toast.makeText(mContext, echo, Toast.LENGTH_SHORT);
toast.show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_borrame);
myJavaScriptInterface = new BorrameActivity.MyJavaScriptInterface(this);
webView = (WebView) findViewById(R.id.mybrowserAuthorise);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(myJavaScriptInterface, "JSInterface");
webView.loadUrl("file:///android_asset/loginProtocol.html");
//webView.loadUrl("javascript:JSInterface.doEchoTest('test')"); // THIS WORKS!!
webView.loadUrl("javascript:testEcho()"); // THIS DOES NOT WORK
}
}
This works when I execute
webView.loadUrl("javascript:JSInterface.doEchoTest('test')");
But it doesn't work when the Javascript function is in loginProtocol.html:
webView.loadUrl("javascript:testEcho()");
Where
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width; user-scalable=0;" />
<title></title>
</head>
<body style="visibility:visible">
<!-- Used for debugging -->
<h1>HELLO</h1>
<script>
function testEcho(){
JSInterface.doEchoTest('This does not get printed in Android Log');
}
</script>
</body>
</html>
and
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sedicii.app.sedicii.BorrameActivity">
<WebView
android:id="#+id/mybrowserAuthorise"
android:layout_width="353dp"
android:layout_height="442dp"/>
</LinearLayout>
The WebView seems to be loading correctly (I can see the HELLO from loginProtocol.html on the Android screen).
What am I missing?
SOLUTION
I have to wait until the HTML page is loaded. Thanks #KosWarm
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
webView.loadUrl("javascript:testEcho()");
}
});
I think you just need to give parameter to your loadUrl method:
webView.loadUrl("javascript:testEcho('Hello World!')");
and your javascript function must look like:
function testEcho(testHello){
window.JSInterface.doEchoTest(testHello);
}
You execute the method loadUrl twice
At the second execution, the first page is closed, so its script can not be executed
The following page code works
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width; user-scalable=0;" />
<title></title>
</head>
<body style="visibility:visible">
<!-- Used for debugging -->
<h1>HELLO</h1>
<script>
function testEcho(){
JSInterface.doEchoTest('This does not get printed in Android Log');
}
testEcho() //added this line
</script>
</body>
</html>
Update
from this place Calling Javascript method from within webview in Android
rewrite Activity onCrete method as
myJavaScriptInterface = new MyJavaScriptInterface(this);
webView = (WebView) findViewById(R.id.mybrowserAuthorise);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(myJavaScriptInterface, "JSInterface");
webView.loadUrl("file:///android_asset/loginProtocol.html");
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
webView.loadUrl("javascript:testEcho()");
}
});
I am able to get HTML source code using following code. but when I am trying with https://marriott.medallia.com/sso/marriott/homepage.do?v=bnAaQvo3*lVHsqtnwluPh_CMCsIHyFkti&alreftoken=6d0d31c7eb7583b964d0ecb89b55e12b
The page URL is getting changed dynamically and on next generated page when I see source view I only get the following code in the HTML body:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>IdP Selection</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="style.min.css">
</head>
<body>
<div id="app-container" class="app-container"></div>
<script>
AppContext = {
idps: '[{"entityId":"MI-PROD-SAML2-IDP-MEDALLIA","name":"Marriott International (any associate w/ EID)"},{"entityId":"https://identity.starwoodhotels.com","name":"Starwood Hotels"}]'
};
</script>
<script src="main.min.js"></script>
</body>
</html>
when I inspect on generated radio button I am able to get HTML element in browser developer elements tab.
My C# code is as follows:
public Form1()
{
InitializeComponent();
this.webBrowser1.ObjectForScripting = new MyScript();
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser1.Navigate("javascript: window.external.CallServerSideCode();");
}
[ComVisible(true)]
public class MyScript
{
public void CallServerSideCode()
{
var doc = ((Form1)Application.OpenForms[0]).webBrowser1.Document;
var renderedHtml = doc.GetElementsByTagName("HTML")[0].OuterHtml;
var marelement = doc.GetElementById("MI-PROD-SAML2-IDP-MEDALLIA");
HtmlElementCollection eCollections = doc.GetElementsByTagName("HTML");
string strDoc = eCollections[0].OuterHtml;
}
}
I think It's because of ajax! After ajax previous handler of element is not updates and you should attach handler on OnPropertyChanged event:
var element = webBrowser.Document.GetElementsByTagName("HTML")[0];
element != null ? element.AttachEventHandler("onpropertychange", handler) : return;
private string renderedHtml;
private void handler(Object sender, EventArgs e)
{
var element = webBrowser.Document.GetElementsByTagName("HTML")[0];
if (element != null)
renderedHtml = element.OuterHtml;
}
So the page is rendered by ReactJS so you are going to have a bad time getting this to work. The best thing I can think of is creating a something that 'waits' for the element to be created in the WebBrowserControl....
!(function() {
function check(){
if(!document.getElementById("MI-PROD-SAML2-IDP-MEDALLIA")) {
setTimeout(check, 100);
} else {
window.external.CallServerSideCode();
}
}
check();
}());
Which can then be minified to something you can use...
webBrowser1.Navigate(#"javascript:!(function(){function c(){if(!document.getElementById('MI-PROD-SAML2-IDP-MEDALLIA')){setTimeout(c, 100);}else{window.external.CallServerSideCode();}}c();}());");
Everything seem OK but when I apply click or perform any other event is not working inside iOS WKWebView with contenteditable. I assumed there is no errors in code. But I think I need to set up something else I don't know.
I need help to overcome with this problem. If there is any trick or alternative please suggest.
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
//Outlets
#IBOutlet weak var containerViewForWKWebView : UIView! //Set background color to very light grey color.
//Variables
var webView: WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Initializing webView
webView = WKWebView()
//Setting delegate and other additional settings for webView
webView?.isUserInteractionEnabled = true
webView?.navigationDelegate = self
webView?.uiDelegate = self
webView?.scrollView.bounces = false
webView?.backgroundColor = UIColor.black //Setting webView background color to black.
//Now adding webView inside containerViewForWKWebView.
containerViewForWKWebView.addSubview(webView!)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//Updating layout for webView.
let frame = CGRect(x: 0.0, y: 0.0, width: containerViewForWKWebView.bounds.width, height: containerViewForWKWebView.bounds.height)
webView?.frame = frame
view.layoutIfNeeded()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func webPageForCheckboxTest(_ sender: UIButton) {
loadLocalWebPageFromBundleMain(webPageFileName: "local-web-page-for-checkbox")
}
#IBAction func intertnetPageForCheckboxTest(_ sender: UIButton) {
let webSiteAddress = URL(string: "http://juntolife.com/for_testing/web-page-for-checkbox.html")
let myURLRequest = URLRequest(url: webSiteAddress!)
webView?.load(myURLRequest)
}
#IBAction func webPageForClickEventTest(_ sender: UIButton) {
loadLocalWebPageFromBundleMain(webPageFileName: "local-web-page-for-clickevent")
}
#IBAction func internetPageForClickEventTest(_ sender: UIButton) {
let webSiteAddress = URL(string: "http://juntolife.com/for_testing/web-page-for-clickevent.html")
let myURLRequest = URLRequest(url: webSiteAddress!)
webView?.load(myURLRequest)
}
func loadLocalWebPageFromBundleMain(webPageFileName: String) {
var htmlString: String!
let webPageURLFromBundleMain = Bundle.main.url(forResource: webPageFileName, withExtension: "html")
let baseURL = webPageURLFromBundleMain?.deletingLastPathComponent()
print("Base URL of Bundle Main: \(baseURL)")
do {
let fileContent = try String(contentsOf: webPageURLFromBundleMain!, encoding: String.Encoding.utf8)
htmlString = fileContent
} catch let error as NSError {
print("Failed getting content of the file: \(webPageURLFromBundleMain), Error: " + error.localizedDescription)
htmlString = ""
}
if htmlString != "" {
webView?.loadHTMLString(htmlString, baseURL: baseURL)
} else {
print("Local web page file is not found in bundle main.")
htmlString = "<!DOCTYPE html><html><body><h3>Local web page file is not found in bundle main.</h3></body></html>"
}
}
}
local-web-page-for-clickevent.html
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>Title</title>
</head>
<body style="background-color:#bce0ff;">
<div>
<h3 style="text-align: center;"><strong>Local Web Page For Click Event Test</strong></h3>
<p>Link outside content editable: This is a dummy link Please click it to see it is working or not.</p>
</div>
<div contenteditable="true" id="content" style="background-color:#ffffff;">
<p>Link inside content editable: This is a dummy link Please click it to see it is working or not.</p>
</div>
<script>
document.querySelector("body").addEventListener('click', function(e) {
var anchor = e.target.closest('a');
if(anchor !== null) {
anchor.innerHTML = Date();
}
}, false);
</script>
</body>
</html>
local-web-page-for-checkbox.html
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>Title</title>
</head>
<body style="background-color:#bce0ff;">
<div>
<h3 style="text-align: center;"><strong>Local Web Page For Check Box Test</strong></h3>
<p>Check box outside content editable: <input type="checkbox" /> This is a checkbox input. Please check it to see it is working or not.</p>
</div>
<div contenteditable="true" id="content" style="background-color:#ffffff;">
<p>Check box inside content editable: <input type="checkbox" /> This is a checkbox input. Please check it to see it is working or not.</p>
</div>
</body>
</html>
I am using John Papa's single page app and I have ran into a problem where on my dev server it doesn't download require.js. It's odd because when I debug in localhost it can find the script.
HTML
#using System.Web.Optimization
<!DOCTYPE html>
<html>
<head>
<title>CCJS</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
#Styles.Render("~/Content/css")
<script>
// Must be first. IE10 mobile viewport fix
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement("style");
var mq = "##-ms-viewport{width:auto!important}";
msViewportStyle.appendChild(document.createTextNode(mq));
document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
}
</script>
<script src="http://yui.yahooapis.com/3.11.0/build/yui/yui-min.js"></script>
#Scripts.Render("~/scripts/modernizr")
</head>
<body>
<div id="applicationHost">
#RenderPage("_splash.cshtml")
</div>
#Scripts.Render("~/scripts/vendor")
<script src="/App/durandal/amd/require.js" data-main="App/main"></script>
</body>
</html>
I am using scriptbundles as well.
using System;
using System.Web;
using System.Web.Optimization;
using System.Web.UI;
namespace AgencyUpdate
{
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
try
{
bundles.IgnoreList.Clear();
AddDefaultIgnorePatterns(bundles.IgnoreList);
bundles.Add(
new ScriptBundle("~/scripts/modernizr")
.Include("~/scripts/modernizr-{version}.js"));
bundles.Add(
new ScriptBundle("~/scripts/vendor")
.Include("~/scripts/jquery-{version}.min.js")
.Include("~/scripts/bootstrap.min.js")
.Include("~/scripts/bootstrap-datepicker.min.js")
.Include("~/scripts/knockout-{version}.js")
.Include("~/scripts/sammy-{version}.min.js")
.Include("~/scripts/moment.min.js")
.Include("~/scripts/Q.min.js")
.Include("~/scripts/breeze.debug.js")
.Include("~/scripts/toastr.min.js")
.Include("~/scripts/apps/exeOnEnter.js")
.Include("~/scripts/custom.js")
.Include("~/scripts/test.js")
.Include("~/scripts/knockout.mapping.js")
.Include("~/scripts/jquery.storage.js")
);
bundles.Add(
new StyleBundle("~/Content/css")
.Include("~/Content/ie10mobile.css")
.Include("~/Content/bootstrap.min.css")
.Include("~/Content/bootstrap-responsive.css")
.Include("~/Content/bootstrap-datepicker.min.css")
.Include("~/Content/font-awesome.min.css")
.Include("~/Content/durandal.css")
.Include("~/Content/toastr.css")
.Include("~/Content/app.css")
.Include("~/Content/styles.css")
.Include("~/Content/custom.css")
);
}
catch (Exception ex)
{
}
}
public static void AddDefaultIgnorePatterns(IgnoreList ignoreList)
{
if (ignoreList == null)
{
throw new ArgumentNullException("ignoreList");
}
ignoreList.Ignore("*.intellisense.js");
ignoreList.Ignore("*-vsdoc.js");
//ignoreList.Ignore("*.debug.js", OptimizationMode.WhenEnabled);
//ignoreList.Ignore("*.min.js", OptimizationMode.WhenDisabled);
//ignoreList.Ignore("*.min.css", OptimizationMode.WhenDisabled);
}
}
}
This is my browser