I wrote a simple jsp page where I am loading an external website inside one of my division.
Below is the code :
<html>
<head>
<script src="../common/jquery-1.6.2.min.js"></script>
<script>
$(document).ready(function(){
$("#menu").html('<object data="www.someurl.com">').appendTo('body');;
});
</script>
</head>
<body>
<div id="menu" style="position:relative; bottom: 0; overflow:hidden;">
</div>
</body>
</html>
Basically what I am doing is that , I am setting an HTML content having a src URL inside the object tag.
This is successful and I can load web URL inside my division.
Question comes when I want to send some data(may be a single variable) using HTTP POST method.
Is there any way to call the same URL using HTTP POST ?
Note : Here I cannot use Jquery POST because of same origin policy.
Try to load the external link or website in an Iframe and try.
<div>
<iframe id="" name="" src="your external link" ></iframe>
</div>
I dont know if you an use php,becouse of the no php tag,but you can post data using HttpRequest class in php,and it is secured !
here is a link : http://php.net/manual/en/class.httprequest.php
Take a look at the Jquery post function: http://api.jquery.com/jQuery.post/
Also, if you want to send some data, along with the url, you can do it with your get as well:
www.someurl.com?dataAttr=someValue&dataOtherAttr=someOtherDataValue
This would be the GET equivalent of a post with the following data:
{
"dataAttr": "someValue",
"dataOtherAttr": "someOtherDataValue"
}
Here is a pure js that will make a post to a server. The script makes an invisible iframe and makes a call to a specified server with the specified parameters. The server has to support the Cross Domain Policy. If you can't make the server support CORS, you are out of luck:
/**
*
* Makes a post to the specified url with the specified param - keyval
*/
makePost = function makePost(url, params){
var iframeId = 'iframeid';
var addParamsToForm = function (form, params){
var addParamToForm = function(form, paramName, paramValue){
var input = document.createElement('input');
input.hidden = 'hidden';
input.name = paramName;
input.value = paramValue;
form.appendChild(input);
}
for ( var prop in params ){
if ( params.hasOwnProperty(prop) ){
if ( params[prop] instanceof Array ){
for ( var i = 0; i < params[prop].length; i ++ ){
addParamToForm(form, prop, params[prop][i]);
}
} else {
addParamToForm(form, prop, params[prop]);
}
}
}
};
var iframe = document.getElementById(iframeId);
if ( iframe === null ){
iframe = document.createElement('iframe');
iframe.name = 'iframeName';
iframe.id = iframeId;
iframe.setAttribute("style", "width: 0; height: 0; border: none; display: none;");
}
var form = document.createElement('form');
form.action = url;
form.method = 'POST';
form.target = iframe.name;
addParamsToForm(form, params);
iframe.appendChild(form);
document.getElementsByTagName('body')[0].appendChild(iframe);
form.submit();
}
example usage:
makePost('yourserver', {'someAttr':'someAttrValue', 'someOtherAttr': 'someOtherAttrValue'});
Or a jquery variant:
$.ajax({
type: 'POST',
url: 'yourserver',
crossDomain: true,
data: {'someAttr':'someAttrValue', 'someOtherAttr': 'someOtherAttrValue'},
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
On tips how to configure your server to support CORS:
http://enable-cors.org/server.html
Take a look at this one:
How do I send a cross-domain POST request via JavaScript?
Related
Using the target attribute of an html form, you can post form data and then have the html-server-response showcased in an iframe.
form.setAttribute("target", "nameOfIframe");
Can the same thing be achieved posting with the ecmascript fetch api (without creating an actual html form element)?
It's fairly trivial to update the content of an IFRAME with JavaScript/EcmaScript and can be done using the srcdoc property.
document.getElementById('fetchTarget').srcdoc = `<!DOCTYPE html><p>Hello World!</p>`;
<iframe id="fetchTarget">
</iframe>
All you would need to do is arrange to update it as part of the processing of the call to fetch:
fetch(`https://jsonplaceholder.typicode.com/posts/1`)
.then(response => {
console.log(response);
if (response.ok){
return response.text();
}
})
.then(text => {
document.getElementById('fetchTarget').srcdoc = text;
});
<iframe id="fetchTarget">
</iframe>
This URL isn't a particularly great example as it returns JSON instead of HTML but it doesn't really affect the result.
I was able to get it the fetch POST response into the iframe by using the srcdoc property of the iframe, as advised to me by this AI answer.
async function sendFetchResponseToIframe()
{
const formData = new FormData();
formData.append('input1', 'value1');
formData.append('input2', 'value2');
let options = {};
options.method = 'POST';
options.mode = 'cors';
options.body = formData;
let postURL = 'http://neartalk.com/test/formData.php';
let response = await fetch(postURL, options);
let data = await response.text();
let iframe = document.getElementById("frame1");
iframe.srcdoc = data;
}
sendFetchResponseToIframe();
<p>The fieldset below contains an iframe that gets updated to the Fetch POST response:</p>
<fieldset>
<legend>Iframe</legend>
<iframe id="frame1" style="width:100%" src="http://www.example.com/" frameborder="0"></iframe>
</fieldset>
However, this method is not as transparent as setting the target of an HTML form, which preserves all relative links that may be returned by a server's HTML response.
While there are methods of addressing this, like: (1) Modifying the html response to include a base element, or (2) modifying the HTML response to convert all relative links to absolute links. I can still imagine other complications like server-side redirects that could ultimately occur. Such redirects would lead to you ultimately having to also modifying your fetch code to follow the redirects, determine the final URL, and convert the base URL or absolute links accordingly.
Due to these complications, the answer to my question is ultimately: No; you're better off creating a hidden HTML form dynamically, and setting its target prior to submission, and then ultimately removing that dynamically created form after submission. This method more easily protects the relative links that could potentially be in the HTML response:
function submitFormToIframe(actionURL, formData, iframe)
{
const form = document.createElement('form');
form.action = actionURL;
form.method = 'POST';
form.target = iframe.name;
for (const [name, value] of formData.entries())
{
const input = document.createElement('input');
input.type = 'hidden';
input.name = name;
input.value = value;
form.appendChild(input);
}
form.style.display = "none";
document.body.append(form);
form.submit();
document.body.removeChild(form);
}
async function main()
{
// Create Form Data:
const formData = new FormData();
formData.append('input1', 'value1');
formData.append('input2', 'value2');
// Get iframe from DOM:
let iframe = document.getElementById("frame1");
let actionURL = 'http://neartalk.com/test/formData.php';
submitFormToIframe(actionURL, formData, iframe);
}
onload = main;
<p>The fieldset below contains an iframe that gets updated via generated form submission:</p>
<fieldset>
<legend>Iframe</legend>
<iframe id="frame1" name="frame1" style="width:100%" src="http://www.example.com/" frameborder="0"></iframe>
</fieldset>
Due to these findings, I think the specification writers, should consider adding a fetch option that allows you to send a fetch response directly to a specified iframe, in a manner where relative links aren't susceptible to breakage (as is the case with HTMLFormElement.target. This would make the fetch API a more attractive solution.
If you need to process the data inside the iframe, you can use window.postMessage(). Instead of iframe.srcdoc property, you can of course put the code in a separate file and reference it via iframe.src
let btn = document.getElementById('btn')
let otherBtn = document.getElementById('btn2')
let wrongBtn = document.getElementById('btn3')
let results = document.getElementById('results')
function showResults(json) {
results.contentWindow.postMessage({
action: 'showResults',
data: json,
}, "*");
}
function sendForm() {
fetch('https://dummyjson.com/products/1')
.then(res => res.json())
.then(showResults)
}
function addLinkToIframe() {
results.contentWindow.postMessage({
action: 'addLink',
data: {
href: 'index.html',
text: 'Click me!',
},
}, "*");
}
function addCallNonExistentAction() {
results.contentWindow.postMessage({
action: 'gibberish',
data: 'even more gibberish',
}, "*");
}
btn.addEventListener('click', sendForm)
otherBtn.addEventListener('click', addLinkToIframe)
wrongBtn.addEventListener('click', addCallNonExistentAction)
window.addEventListener('message', (event) => {
if (event.data.action === 'iframe::DOMContentLoaded') {
console.log('iframe loaded');
results.contentWindow.postMessage({
action: 'setBase',
data: document.baseURI,
}, "*");
} else {
alert(`Action '${event.data.action}' not defined`)
}
})
<button id="btn">Send</button>
<button id="btn2">Add link</button>
<button id="btn3">Call non-existent action</button>
<hr />
<iframe id="results" srcdoc="<!DOCTYPE html>
<html>
<head>
<base href=>
<script>
window.addEventListener('message', (event) => {
if (event.data.action === 'showResults') {
document.body.querySelector('pre').appendChild(
document.createTextNode(JSON.stringify(event.data.data, true, '\t'))
);
} else if (event.data.action === 'setBase') {
console.log('setbase')
document.head.querySelector('base').href = event.data.data
console.log(document.baseURI)
} else if (event.data.action === 'addLink') {
link = Object.assign(document.createElement('a'), {
href: event.data.data.href,
})
link.textContent = event.data.data.text
console.log('add', link)
document.body.prepend(link);
} else {
alert(`Action '${event.data.action}' not defined`)
}
})
window.parent.postMessage({
action: 'iframe::DOMContentLoaded',
}, '*')
</script>
</head>
<body>
Waiting ...
<pre></pre>
</body>
</html>
"></iframe>
<script>
window.addEventListener('load',function(){
var unique_code="3412313ad"// Initialize it with the unique code provided to you.
var param1="1"; // Initialize this with the value that you wish to see.For example 1 for navbar display , 2 for the side floating pop up
//while 3 for a transparent overlay on the whole page.
var domain=window.location.hostname;// current domain.
function jsonp(url, callback) {
var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
window[callbackName] = function(data) {
delete window[callbackName];
document.body.removeChild(script);
callback(data);
};
var script = document.createElement('script');
script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName;
document.body.appendChild(script);
script.onerror=function(){
alert("failed to load snippet!");
}
}
jsonp('http://localhost/server.php?unique_code='+unique_code+'&domain='+domain, function(data) {
alert(data);
if(data.status=='success'){
alert('success');
}else alert(data.reason);
});
});
</script>
This is a code that mimics jsonp of the jquery to get a script from the remote server.
I used the answer given in this question JavaScript XMLHttpRequest using JsonP
Server side code would be
if(isset($_GET['unique_code']) && !empty($_GET['unique_code']) && isset($_GET['domain']) && !empty($_GET['domain'])){
$unique_code=$_GET['unique_code'];
$domain=$_GET['domain'];
$statement=$mysqli->prepare('select * from `snippet_users` where unique_code=? AND domain=?');
$statement->bind_param('ss',$unique_code,$domain);
if(!$statement->execute())
die(json_encode(array('status'=>'error','reason'=>'Server error.')));
$result=$statement->get_result();
if(mysqli_num_rows($result)>0)
die (json_encode(array('status'=>'success')));
else die(json_encode(array('status'=>'error','reason'=>'Unique code/Domain error.')));
}else{
die(json_encode(array('status'=>'error','reason'=>'Unique code/Domain error.')));
}
Everything is working perfectly fine but i see error in the console , somewhat like this :
What would be my solution so that i dont get this error as well as i get my data in the alert box?
You are outputting application/json instead of application/javascript, so your browser thinks it's not valid. The json should be in a function call (callback parameter). The callback parameter should be validated on the server side however to prevent xss injection:
Is it necessary to validate or escape the jsonp callback string
I have set up Bootstraps nav-tabs via an index page. Each tab loads a seperate PHP file via AJAX:
<div class="container">
<ul class="nav nav-tabs" id="indextabs">
<li>NOTES</li>
<li>WHOIS</li>
<li>DIG</li>
<li>ETS</li>
<li>RESOURCES</li>
</ul>
</div>
JavaScript that takes care of the AJAX queries:
window.onload = function() {
$('[data-toggle="tabchange"]').click(function(e) {
var $this = $(this),
loadurl = $this.attr('href'),
targ = $this.attr('data-target');
$.get(loadurl, function(data) {
$(targ).html(data);
});
$this.tab('show');
return false;
});
}
This itself works fine. In some of the tabs, however, there is an input that requires a domain name which then needs to be submitted via a GET request so that the URL can be something like:
http://domain.com/?domain=google.com&record=mx
With this in mind, I have two problems:
How do I load a particular tab using a GET method URL?
How do I submit form data via AJAX using the GET method and have it change the URL AND load the content in the tab-panel divs?
Please consider the following more like a comment because I'm uncertain what's optimal (and also works) in your case. Anyway I think you need to pass query parameters in your $get method call, either in form of a object, key value pairs { domain: 'google.com', record: 'mx'} or as string. Below an object/key value pairs are used.
window.onload = function() {
$('[data-toggle="tabchange"]').click(function(e) {
var $this = $(this),
loadurl = $this.attr('href'),
targ = $this.attr('data-target');
//optional method call below, uncomment if needed
//loadurl = getDomainURL() + "/" + loadurl
$.get(loadurl, {
domain: 'google.com',
record: 'mx'
},
function(data) {
$(targ).html(data);
});
$this.tab('show');
return false;
});
}
//returns domain name: www.example.com in form of http://example.com
// or domain name: http://example.com is returned as it is, unchanged http://example.com
function getDomainURL() {
var index = window.location.hostname.indexOf("www.");
if (index === 0)
return "http://" + window.location.hostname.substr((index + 4));
else
return "http://" + window.location.hostname;
}
I can't seem to get my Access Token through the Nest API.
I've tried POSTing to the Access Token URL in 3 different ways, but they all give the same result.
I'm using the following code:
<body>
<button type = 'button' id = 'connect' class = 'btn btn-default'>Connect To Nest</button>
<div id = 'pinArea'>
<label for = 'pin'>Enter PIN Here: </label><input type = 'text' name = 'pin' id = 'pin'><br />
<button type = 'button' class = 'btn btn-default' id = 'pinSubmit'>Submit</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script type = 'text/javascript'>
$(document).ready(function() {
function makeid()
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
$("#connect").click(function() {
var state = makeid();
window.open('https://home.nest.com/login/oauth2?client_id=MYCLIENTID&state='+state+'');
$("#connect").hide();
$("#pinArea").show();
});
$("#pinSubmit").click(function() {
var pin = $("#pin").val();
$.ajax({
url: "https://api.home.nest.com/oauth2/access_token?code="+pin+"&client_id=MYCLIENTID&client_secret=MYCIENTSECRET&grant_type=authorization_code",
//data: {code: pin, client_id: "MYCLIENTID", client_secret: "MMYCLIENTSECRET", grant_type: "authorization_code"},
type: "POST",
success: function(res) {
console.log(res);
},
error: function(e) {
console.log(e);
}
});
});
});
</script>
The problem is that the URL is giving the following error in my console, when it should be sending back my Access Token:
XMLHttpRequest cannot load https://api.home.nest.com/oauth2/access_token. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fatslug.ca' is therefore not allowed access.
Any ideas on what could be causing this? Am I just doing it completely wrong?!
The issue is that Nest does not support CORs for their token exchange step. I presume this is intentional, but I'm really not sure.
Instead, Nest would seem to prefer that you build a server and proxy the token exchange through that server. Pretty simple to do.
However, if you really want to do the token exchange in the browser (and do NOT do this for anything in production or taking privacy/security seriously), then you can use a service like cors-anywhere.com:
"https://cors-anywhere.herokuapp.com/api.home.nest.com/oauth2/access_token?" +
"code="+auth.authorizationCode+"&" +
"client_id="+clientId+"&" +
"client_secret="+clientSecret+"&" +
"grant_type=authorization_code"
This will send the request to cors-anywhere, which will provide CORs support to the request and proxy to Nest.
I don't think it has anything to do with CORS so much as Nest requiring a POST.
I have a link: Hello.
When someone clicks the link I'd like to check via JavaScript if the page the href-attribute points to exists or not. If the page exists the browser redirects to that page ("www.example.com" in this example) but if the page doesn't exist the browser should redirect to another URL.
It depends on whether the page exists on the same domain or not. If you're trying to determine if a page on an external domain exists, it won't work – browser security prevents cross-domain calls (the same-origin policy).
If it is on the same domain however, you can use jQuery like Buh Buh suggested. Although I'd recommend doing a HEAD-request instead of the GET-request the default $.ajax() method does – the $.ajax() method will download the entire page. Doing a HEAD request will only return the headers and indicate whether the page exists (response codes 200 - 299) or not (response codes 400 - 499). Example:
$.ajax({
type: 'HEAD',
url: 'http://yoursite.com/page.html',
success: function() {
// page exists
},
error: function() {
// page does not exist
}
});
See also: http://api.jquery.com/jQuery.ajax/
A pretty good work around is to proxy. If you don't have access to a server side you can use YQL. Visit: http://developer.yahoo.com/yql/console/
From there you can do something like: select * from htmlstring where url="http://google.com". You can use the "REST query" they have on that page as a starting point for your code.
Here's some code that would accept a full URL and use YQL to detect if that page exists:
function isURLReal(fullyQualifiedURL) {
var URL = encodeURIComponent(fullyQualifiedURL),
dfd = $.Deferred(),
checkURLPromise = $.getJSON('http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20htmlstring%20where%20url%3D%22' + URL + '%22&format=json');
checkURLPromise
.done(function(response) {
// results should be null if the page 404s or the domain doesn't work
if (response.query.results) {
dfd.resolve(true);
} else {
dfd.reject(false);
}
})
.fail(function() {
dfd.reject('failed');
});
return dfd.promise();
}
// usage
isURLReal('http://google.com')
.done(function(result) {
// yes, or request succeded
})
.fail(function(result) {
// no, or request failed
});
Update August 2nd, 2017
It looks like Yahoo deprecated "select * from html", although "select * from htmlstring" does work.
Based on the documentation for XMLHttpRequest:
function returnStatus(req, status) {
//console.log(req);
if(status == 200) {
console.log("The url is available");
// send an event
}
else {
console.log("The url returned status code " + status);
// send a different event
}
}
function fetchStatus(address) {
var client = new XMLHttpRequest();
client.onreadystatechange = function() {
// in case of network errors this might not give reliable results
if(this.readyState == 4)
returnStatus(this, this.status);
}
client.open("HEAD", address);
client.send();
}
fetchStatus("/");
This will however only work for URLs within the same domain as the current URL. Do you want to be able to ping external services? If so, you could create a simple script on the server which does your job for you, and use javascript to call it.
If it is in the same domain, you can make a head request with the xmlhttprequest object [ajax] and check the status code.
If it is in another domain, make an xmlhttprequest to the server and have it make the call to see if it is up.
why not just create a custom 404 handler on the web server? this is probably the more "good-bear" way to do this.
$.ajax({
url: "http://something/whatever.docx",
method: "HEAD",
statusCode: {
404: function () {
alert('not found');
},
200: function() {
alert("foundfile exists");
}
}
});
If you are happy to use jQuery you could do something like this.
When the page loads make an ajax call for each link. Then just replace the href of all the links which fail.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
<!--
$.fn.checkPageExists = function(defaultUrl){
$.each(this, function(){
var $link = $(this);
$.ajax({
url: $link.attr("href"),
error: function(){
$link.attr("href", defaultUrl);
}
});
});
};
$(document).ready(function(){
$("a").checkPageExists("default.html");
});
//-->
</script>
You won't be able to use an ajax call to ping the website because of same-origin policy.
The best way to do it is to use an image and if you know the website you are calling has a favicon or some sort of icon to grab, you can just use an html image tag and use the onerror event.
Example:
function pingImgOnWebsite(url) {
var img = document.createElement('img');
img.style.visibility = 'hidden';
img.style.position = 'fixed';
img.src = url;
img.onerror = continueBtn; // What to do on error function
document.body.appendChild(img);
}
Another way to do this is is with PHP.
You could add
<?php
if (file_exists('/index.php'))
{
$url = '/index.php';
} else {
$url = '/notindex.php';
}
?>
And then
<a href="<?php echo $url; ?>Link</a>