I'm trying to get the source code form a URL web page using JSONP.
This is the code:
<script type="text/javascript">
var your_url = '';
$(document).ready(function(){
jQuery.ajax = (function(_ajax){
var protocol = location.protocol,
hostname = location.hostname,
exRegex = RegExp(protocol + '//' + hostname),
YQL = 'http' + (/^https/.test(protocol)?'s':'') + '://query.yahooapis.com/v1/public/yql?callback=?',
query = 'select * from html where url="{URL}" and xpath="*"';
function isExternal(url) {
return !exRegex.test(url) && /:\/\//.test(url);
}
return function(o) {
var url = o.url;
if ( /get/i.test(o.type) && !/json/i.test(o.dataType) && isExternal(url) ) {
// Manipulate options so that JSONP-x request is made to YQL
o.url = YQL;
o.dataType = 'json';
o.data = {
q: query.replace(
'{URL}',
url + (o.data ?
(/\?/.test(url) ? '&' : '?') + jQuery.param(o.data)
: '')
),
format: 'xml'
};
// Since it's a JSONP request
// complete === success
if (!o.success && o.complete) {
o.success = o.complete;
delete o.complete;
}
o.success = (function(_success){
return function(data) {
if (_success) {
// Fake XHR callback.
_success.call(this, {
responseText: data.results[0]
// YQL screws with <script>s
// Get rid of them
.replace(/<script[^>]+?\/>|<script(.|\s)*?\/script>/gi, '')
}, 'success');
}
};
})(o.success);
}
return _ajax.apply(this, arguments);
};
})(jQuery.ajax);
$.ajax({
url: your_url,
type: 'GET',
success: function(res) {
var text = res.responseText;
//document.getElementById("contenuto").innerHTML = text;
alert(text);
}
});
});
</script>
I printed with an alert all the source code, from the URL.
alert(text);
First, how to know if the printed code is all the web code of the page?
If I try to do in this way
document.getElementById("contenuto").innerHTML = text;
this is the result:
\ \ <'+'/ins>\ \ \ '); } ]]>
I tried to use HTML DOM to print just one element, doing in this way
document.getElementById("contenuto").innerHTML = text;
var elem = text.getElementById("strip_adv").innerHTML;
document.getElementById("contenuto_1").innerHTML = elem;
}
But this is the error on the JS console:
text.getElementById is not a function
Recap:
I would to get the source code of a web page from URL, using JSONP.
I would use HTML DOM from the returned text, to keep only the element/class I need. I'm a newbie on JS, I'm trying to learn more & more about JS.
getElementById() is present only in the document object. What you are trying to do is trying to access getElementId from a string object.
Instead what I would suggest is insert the returned html string inside iframe and you can access the elements within iframe otherwise you can use some kind of html parser in your application.
lets say your html looks like this after you insert your html string inside iframe
<body>
<iframe id="one">
<html>
<body> <h1 id="strip_adv">Heading</h1> </body>
</html
</iframe>
</body>
function iframeObj( frameEle ) {
return frameEle.contentWindow
? frameEle.contentWindow.document
: frameEle.contentDocument
}
var element = iframeObj( document.getElementById('strip_adv') );
Related
I simply would like to replace the <main>-Element and it's content of firstPage.html ...
// ... header of my 1st document ...
<body>
<main>
The content of the 1st document...
</main>
</body>
// ... footer of my 1st document ...
... with the <main>-Element and it's content of secondPage.html ...
secondPage.html
// ... header of my 2nd document ...
<body>
<main>
The content of the 2nd document...
</main>
</body>
// ... footer of my 2nd document ...
... using AJAX call by plain JavaScript. How could I do that?
I am able to several methods to load 2nd document completely into the 1st one but I can't find any solution in JavaScript to load only specific HTML-element from another URL into DOM of 1st document. :(
UPDATE/EDIT:
This is my status quo of my ajax function:
var myLoad = ( type, url, data, success ) => {
var d = data ? ( typeof data == 'string' ) ? data : Object.keys(data).map(k=>( encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) )).join('&') : '' ;
var u = (d && type==='GET') ? url+'?'+d : url ;
var x = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
x.open(type,u);
x.onreadystatechange = () => {
if( x.readyState > 3 && x.status == 200 ){
success(x.responseText)
}
};
x.setRequestHeader('X-Requested-With','XMLHttpRequest');
if( type === 'POST' ){
x.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
x.send(d);
} else {
x.send();
}
return x;
};
myLoad( 'GET', 'secondPage.html', '', r => {
// of course this loads the whole document (secondPage.html) into <main>
// but how to do otherwise ???
document.querySelector('main').innerHTML = r;
};
You could do it using the fetch API to get the HTML as text.
Then you parse it to HTML using the DOMParser to get the new HTML and add it to the old <main>.
In this case, I added the HTML as soon as the DOM was loaded (DOMContentLoaded), but you could eventually change it to whatever suits your needs:
document.addEventListener('DOMContentLoaded', DOMContentLoadedJS, false);
function DOMContentLoadedJS(event) {
//fetch html as text
fetch("/page2.html").then(response => response.text()).then(AfterFetchingHTML);
}
function AfterFetchingHTML(htmlText) {
let main1 = document.querySelector("main"); //<main> on page1.html
let htmlParser = new DOMParser();
let htmlDoc = htmlParser.parseFromString(htmlText, "text/html");
let main2 = htmlDoc.querySelector("main"); //main on page2.html
//clear children from first <main>
while (main1.firstChild) main1.removeChild(main1.firstChild);
//add new <main>
main1.innerHTML = main2.innerHTML;
}
First, this is a google-app-script issue... I can't seem to capture the second (or subsequent) parameters within the HTML page (i.e. "item" in this example)... I've seen many examples using "location.search" and "window.location.search", but none of these seem to work. Could it possibly be as simple as "location.search" is not the correct usage?
Example
Code.gs
var myParam;
/**
* Get the URL for the Google Apps Script running as a WebApp.
*/
function getScriptUrl() {
var url = ScriptApp.getService().getUrl();
return url;
}
/**
* Get "home page", or a requested page.
* Expects a 'page' parameter in querystring.
*
* #param {event} e Event passed to doGet, with querystring
* #returns {String/html} Html to be served
*/
function doGet(e) {
//Logger.log( Utilities.jsonStringify(e) );
Logger.log(e.parameter.page);
var pgToLoad = e.parameter.page;
if (!e.parameter.page) {
Logger.log('!e.parameter.page')
// When no specific page requested, return "home page"
// return HtmlService.createTemplateFromFile('my1').evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
return HtmlService.createTemplateFromFile('my1').evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
Logger.log('there is something for the page');
// else, use page parameter to pick an html file from the script
// return HtmlService.createTemplateFromFile(pgToLoad).evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
return HtmlService.createTemplateFromFile(pgToLoad).evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
I have multiple HTML files, but they are basically the same as my1.html below...
my1.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Source = my1.html</h1>
<p id=myParam>Placeholder</p>
<?var url = getScriptUrl();?><a href='<?=url?>?page=my2&item=1-234'> <input type='button' name='button' value='my2.html'></a>
<?var url = getScriptUrl();?><a href='<?=url?>?page=my3&item=1-345'> <input type='button' name='button' value='my3.html'></a>
</body>
</html>
<script>
function getParam(sname)
{
var params = location.search;
var sval = "";
params = params.split("&");
// split param and value into individual pieces
for (var i=0; i<params.length; i++)
{
temp = params[i].split("=");
if ( temp[0] == sname ) { sval = temp[1]; }
}
return sval;
}
function changeItem() {
var param = getParam("item");
var myItem = "Item:-"+param+"-";
document.getElementById("myParam").innerHTML = myItem;
}
window.onload = changeItem;
</script>
I think I know what you want to do. It looks like you are getting the search string parameters from the doGet(e) function on the server side, then you are trying to get the same search string parameters again on the "client side" from the onload function? If this is the case, I would abandon trying to get the search string parameters from the client side.
You could store the search string parameters in the browsers sessionStorage:
window.sessionStorage.setItem("searchStringOne","Value One");
and to retrieve:
var valueOne = window.sessionStorage.getItem("searchStringOne");
Session Storage Information
Here's an example to show how to get the query string parameters to serve different html templates using html-service of app script :
function doGet(e) {
Logger.log( Utilities.jsonStringify(e) );
// Load a home page when no parameter is specified
if (!e.parameter.redirect) {
var template = HtmlService.createTemplateFromFile('home');
var htmlOutput = template.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME).setTitle('Home');
return htmlOutput;
}
//get the page from parameter and load it
else{
var template=HtmlService.createTemplateFromFile(e.parameter['redirect']);
var htmlOutput = template.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME).setTitle('Other Page');
return htmlOutput;
}
}
function getScriptUrl() {
var url = ScriptApp.getService().getUrl();
return url;
}
then HTML will look like this :
home.html
<?var url = getScriptUrl();?>
You are on Home Page.
<a href='<?=url?>?redirect=pagex'>Goto PageX</a>
<a href='<?=url?>?redirect=pagey'>Goto PageY</a>
pagex.html
You are on PageX
pagey.html
You are on PageY
Hope this helps!
What is the best way to download a dynamically created zip file using AngularJS? I can hit the URL using window.open, but this seems very un-Angular, I could use an iframe, but I don't know how I would get a reference to it in my RestService.
What would be a good Angular implementation to allow for downloading of dynamically created files?
// Current solution
RestService.createInstance( data )
.then(function( id) {
//return RestService.generateArchive( id );
var url = location.href;
if( url.indexOf('#') != -1 ) { url = url.substring(0, url.indexOf('#')); }
url += '?ID=' + id;
window.open( url );
})
.then(function( success ) {
// Obviously won't work due to security
});
Also, how would you check if the response was rejected? Seems like you can't, but just in case.
Small sample :
Html :
<iframe ng-src="{{url}}" style="display:none"/>
JS:
$scope.url = 'google.com';
RestService.createInstance( data )
.then(function( id) {
//return RestService.generateArchive( id );
var url = location.href;
if( url.indexOf('#') != -1 ) { url = url.substring(0, url.indexOf('#')); }
url += '?ID=' + id;
$scope.url = $sce.trustAsResourceUrl(url);
})
This should work some remarks :
ofcourse don't forget to inject $sce
If you download multiple times from the same url, reset the url between downloads to something like google.com
I have a MVC3 action method with 3 parameters like this:
var url = "/Question/Insert?" + "_strTitle='" + title + "'&_strContent='" + content + "'&_listTags='" + listTags.toString() + "'";
and I want to call this by normal javascript function not AJAX (because it's not necessary to use AJAX function)
I tried to use this function but it didn't work:
window.location.assign(url);
It didn't jump to Insert action of QuestionController.
Is there someone would like to help me? Thanks a lot
This is more detail
I want to insert new Question to database, but I must get data from CKeditor, so I have to use this function below to get and validate data
// insert new question
$("#btnDangCauHoi").click(function () {
//validate input data
//chủ đề câu hỏi
var title = $("#txtTitle").val();
if (title == "") {
alert("bạn chưa nhập chủ đề câu hỏi");
return;
}
//nội dung câu hỏi
var content = GetContents();
content = "xyz";
if (content == "") {
alert("bạn chưa nhập nội dung câu hỏi");
return;
}
//danh sách Tag
var listTags = new Array();
var Tags = $("#list_tag").children();
if (Tags.length == 0) {
alert("bạn chưa chọn tag cho câu hỏi");
return;
}
for (var i = 0; i < Tags.length; i++) {
var id = Tags[i].id;
listTags[i] = id;
//var e = listTags[i];
}
var data = {
"_strTitle": title,
"_strContent": content,
"_listTags": listTags.toString()
};
// $.post(url, data, function (result) {
// alert(result);
// });
var url = "/Question/Insert?" + "_strTitle='" + title + "'&_strContent='" + content + "'&_listTags='" + listTags.toString() + "'";
window.location.assign(url); // I try to use this, and window.location also but they're not working
});
This URL call MVC action "Insert" below by POST method
[HttpPost]
[ValidateInput(false)]
public ActionResult Insert(string _strTitle, string _strContent, string _listTags)
{
try
{
//some code here
}
catch(Exception ex)
{
//if some error come up
ViewBag.Message = ex.Message;
return View("Error");
}
// if insert new question success
return RedirectToAction("Index","Question");
}
If insert action success, it will redirect to index page where listing all question include new question is already inserted. If not, it will show error page. So, that's reason I don't use AJAX
Is there some one help me? Thanks :)
Try:
window.location = yourUrl;
Also, try and use Fiddler or some other similar tool to see whether the redirection takes place.
EDIT:
You action is expecting an HTTP POST method, but using window.location will cause GET method. That is the reason why your action is never called.
[HttpPost]
[ValidateInput(false)]
public ActionResult Insert(string _strTitle, string _strContent, string _listTags)
{
// Your code
}
Either change to HttpGet (which you should not) or use jQuery or other library that support Ajax in order to perform POST. You should not use GET method to update data. It will cause so many security problems for your that you would not know where to start with when tackling the problem.
Considering that you are already using jQuery, you might as well go all the way and use Ajax. Use $.post() method to perform HTTP POST operation.
Inside a callback function of the $.post() you can return false at the end in order to prevent redirection to Error or Index views.
$.post("your_url", function() {
// Do something
return false; // prevents redirection
});
That's about it.
You could try changing
var url = "/Question/Insert?" + "_strTitle='" + title + "'&_strContent='" + content + "'&_listTags='" + listTags.toString() + "'";
to
var url = "/Question/Insert?_strTitle=" + title + "&_strContent=" + content + "&_listTags=" + listTags.toString();
I've removed the single quotes as they're not required.
Without seeing your php code though it's not easy to work out where the problem is.
When you say "It didn't jump to Insert action of QuestionController." do you mean that the browser didn't load that page or that when the url was loaded it didn't route to the expected controller/action?
You could use an iframe if you want to avoid using AJAX, but I would recommend using AJAX
<iframe src="" id="loader"></iframe>
<script>
document.getElementById("loader").src = url;
</script>
Basically, I want to have an interactive button on my website, that, when clicked, sends some data to the server in order to be checked and display the response (without form sending / page reload).
I thought it would be something like:
function checkData()
{
var req = new XMLHttpRequest();
var conf = document.getElementById('my_text_area').value;
req.open("GET", 'check_data', true);
req.onreadystatechange = function ()
{
var pre = document.getElementById('check_data_out');
pre.innerHTML = req.responseText;
}
req.send(conf);
return false;
}
And on the server side:
#get('/check_data')
def check_data():
# Process the content and answer something...
content = str(request.is_ajax) + ' - ' + str(request.GET) + ' - ' + str(request.POST)
return content
But this obviously doesn't work. Either it is not the right way to send data via javascript or not the right way to access it in bottle.py.
Showing me how it works is highly appreciated.
You can use dojo for client side logic.
var button = dojo.byId('button_id'); // button_id refers to the id of the button you want to click
dojo.connect(button,'onclick',dojo.xhrGet({
url: '/check_data',
handleAs : 'text',
load : function(response){
dojo.byId('button_id').innerHTML = response;
}
}));