How to get page content using Javascript or JQuery - c#

I will have a widget on a remote page. In the widget I want javascript or jquery to get all the article content from the webpage and send it back to my website. I only need just the article content and not all the other information on the webpage. I would like the script to send the remote webpage url, page content, title text, and h1 text. I would not like to receive any html tags. Is this possible to do?
The script I am making is like google adsense.
Also, Ill be using c# as my backend server
will something like this work?
http://blog.nparashuram.com/2009/08/screen-scraping-with-javascript-firebug.html

my suggestion, if it's not too much data would be to use a beacon.
var beac = new Image();
beac.onload = function () {
//do somethiringng on completion
}
beac.src = "youdomain/somthing.php?var=asdasd&key=someUniqueString";
This allows you to send a moderate amount of data to a server on another domain, provided you don't need anything back.

In short you can't do this, at least not in the way you were expecting. For security reasons there's a same-origin policy in place that prevents you from making requests to another domain.
Your best option is to do this on your server and make the request to it. I can't speak as to how you'd do this on the server since your question doesn't include which framework you're on, but let's say it's PHP, then you'd have that page take a URL, or something you can generate the URL from, then return a JSON object containing the properties you listed. The jQuery part would look something like this:
$("a").click(function() {
$.ajax({
url: 'myPage.php',
data: { url: $(this).attr("href") },
dataType: 'json',
success: function(data) {
//use the properties, data.url, data.content, data.title, etc...
}
});
});
Or, the short form using $.getJSON()...
$.getJSON('myPage.php', { url: $(this).attr("href") }, function(data) {
//use the properties, data.url, data.content, data.title, etc...
});
All the above not withstanding, you're better off sending the URL to your server and doing this completely server-side, it'll be less work. If you're aiming to view the client's page as they would see it...well this is exactly what the same-origin policy is in place to prevent, e.g. what if instead of an article it was their online banking? You can see why this is prohibited :)

Related

How can I load a WebForms page into an iframe without two full page renders from the server?

I have a sort of shell page that contains filter controls and an iframe for displaying a gridview. When you click the 'filter' button, or when a timer is fired, filter data is collected from the filter controls and fed in the querystring to the gridview iframe, as shown:
var URL = "/mypage/gridview.aspx";
var dest = URL + '?' + getFilterData();
var frame = $('#gridiframe');
$.ajax({
type: "HEAD",
async: true,
url: dest
}).success(function () {
frame.attr('src', dest);
})
.error(loadError);
My conundrum is this: the gridview can be very costly to render. It performs a HUGE database trip and this method is causing the page to be rendered twice. The first time, the client just looks at the header to make sure the user is authenticated (page returns HTTP unauthorized if session has timed out) and that all the parameters are in a good format. But I don't want to change the iframe source to show an error message, I just want to call loadError which basically just notifies the user what went wrong.
Is there anything I can do with the client code to populate my iframe in only one exchange with the server?
edit: thanks all for your input. At the end of the day, I hate webforms. End of story.
Instead of querying the iframe's source URL in the ajax query, query a different endpoint that doesn't run the same DB query. You said it does two things, 1 validate the user's login token is still valid and 2 that the filter parameters are valid. Neither of those validation steps require running the query on the database that get the full query results. So, create a new API endpoint that does your basic validation, and if that returns a success message, then set the iframe source to what you want.
Another option is to return a HTML fragment, rather than a full HTML page, from gridview.aspx. Then your AJAX can replace the contents of a div with the HTML result if successful, rather than setting the iframe src, while still allowing you to handle errors.
A more trendy option (not saying it's better or worse, but certainly more aligned with the current web development industry) is to change gridview.aspx to a web service/api that returns the data in simplified json, then use a javascript framework, or template engine to generate the html table on the client itself.
Maybe I'm over-simplifying things, but couldn't you just use a QueryString parameter in the second request?
$.ajax({
type: "HEAD",
async: true,
url: dest
}).success(function () {
frame.attr('src', dest + '&getGrid=true');
})
And then on the aspx page check if the QueryString is present.
protected void Page_Load(object sender, EventArgs e)
{
//validate user always
if (Request.QueryString["getGrid"] != null)
{
//rebuild grid
}
}
Instead of an iFrame you can a normal <div> and load only the gridView from another page as follows:
First, Wrap the gridView around a container in the other page
Something like
<div id='grid-wrapper'><!-- GridView here --></div>
Then use your AJAX code like this to retrieve only the grid:
var URL = "/mypage/gridview.aspx";
var dest = URL + '?' + getFilterData();
var div = $('#divId');
$.ajax({
type: "HEAD",
async: true,
url: dest
}).success(function (res) {
div.html($('#grid-wrapper',$(res)).html); //this gets only the contents of grid-wrapper and not the whole page.
})

Call C# function from Javascript in aspx webform and then reload page

Trying to figure out how to call a c# function in a webform. I tried both ajax and windows.location but could just be off on my path. Trying to send it my c# code at SpeakerList.aspx/update and then gonna attach two variables i have in javascript which shouldnt be too bad. But want it to hit the C# function then reload the page so hoping there is just an easy call im missing.
buttons: {
"Save": function () {
var combo = ASPxClientControl.GetControlCollection().GetByName('DropDownList1');
var value = combo.GetSelectedItem().value;
var billID = $("#billID").val();
window.location = "SpeakerList.aspx/updateRec";
}
You might want to try using WebMethods:
http://aspalliance.com/1922_PageMethods_In_ASPNET_AJAX.all
This allows you to call a function in your page's code behind using JavaScript.
Assuming you are using MVC, you probably want to return a JSON result. An easy way to consume Json within your client webpage is using JQuery. You can return JSON as as the output of a webpage, but I don't recommend it. Create a separate service point that repesents the JSON method.
It is hard to tell what you are actually trying to accomplish, but the normal usage pattern for a JSON method is the supply the parameters as part of the querystring (which you can refactor with routing if you want). The result is then just a JSON packet.
Personally, I like JSON.Net for server side JSON, but you don't actually need this. Look up JSONMethod for examples, etc. that will show you how to do this.
From the browser client, JQuery has a json method, but I personally recommend using the more generic ajax method a JQuery so you can use the handlers for success, error and completion. E.g.
$.ajax({
url: "http:...",
data: queryparm,
cache:false,
timeout:15000,
success: function(data){
jresult = $.parseJSON(data);
...
},
error:function (xhr, ajaxOptions, thrownError)
{
setErrorMsg("Error getting search results: " + thrownError);
}
});
EDIT -- Actually, I've done this exact same thing with webforms too, code is essentially identically (if you use JSON.Net on the server side). You don't have the routing options to make the urls REST compliant, but as an internal json web service, you probably won't really care about that.
As a webpage (.aspx) page, you can use a "postback" this is the simplest method for a web form. You can always declare some hidden fields to use for data passing if you are not passing back a native "control" value. If you don't know how to do this, you need to read a tutorial on using web forms.

Using .ajaxForm and C# MVC, how can I prevent Internet Explorer from trying to save Json result?

I'm returning some Json via a C# MVC Controller. Other browsers work fine, but Internet Explorer (IE9) tries to Save the returned Json data as a Text file. Any ideas how to keep this from happening?
//MVC Controller Code...
return Json(new { redirectToUrl = Url.Action("Create", "Album",
new { url = url, isLocalFile = isLocalFile})});
//Clientside Javascript Code
$("#uploadImageForm").ajaxForm({
beforeSubmit: function () {
},
success: function (data, textStatus, xhr) {
window.location.href = data.redirectToUrl;
},
error: function (data, textStatus, xhr) {
}
});
I've tried adding "text/plain" and "text/json" to the second argument of the return Json method, it doesn't work.
Many thanks!
Quote from the documentation of the jquery.form plugin:
Browsers that support the XMLHttpRequest Level 2 will be able to
upload files seamlessly and even get progress updates as the upload
proceeds. For older browsers, a fallback technology is used which
involves iframes since it is not possible to upload files using the
level 1 implmenentation of the XMLHttpRequest object. This is a common
fallback technique, but it has inherent limitations. The iframe
element is used as the target of the form's submit operation which
means that the server response is written to the iframe. This is fine
if the response type is HTML or XML, but doesn't work as well if the
response type is script or JSON, both of which often contain
characters that need to be repesented using entity references when
found in HTML markup.
To account for the challenges of script and JSON responses when using
the iframe mode, the Form Plugin allows these responses to be embedded
in a textarea element and it is recommended that you do so for these
response types when used in conjuction with file uploads and older
browsers. Please note, however, that if there is no file input in the
form then the request uses normal XHR to submit the form (not an
iframe). This puts the burden on your server code to know when to use
a textarea and when not to.
This means that if your form contains file input fields and you are submitting this form to a controller action that returns JSON, you must wrap this JSON in a <textarea> tags.
So your response should not look like this:
{ "redirectToUrl":"some url" }
it should look like this:
<textarea>{ "redirectToUrl":"some url" }</textarea>
In order to achieve that you could use a custom action result that will wrap the response with those tags:
public class TextareaJsonResult : JsonResult
{
public TextareaJsonResult(object data)
{
this.Data = data;
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
bool shouldWrap = !context.HttpContext.Request.IsAjaxRequest();
if (shouldWrap)
{
response.Write("<textarea>");
}
base.ExecuteResult(context);
if (shouldWrap)
{
response.ContentType = "text/html";
response.Write("</textarea>");
}
}
}
and then have your controller action return this custom result:
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
// ... some processing
var redirectToUrl = Url.Action(
"Create",
"Album",
new { url = url, isLocalFile = isLocalFile }
);
return new TextareaJsonResult(new { redirectToUrl = redirectToUrl });
}
Now obviously in your AJAX success callback you also need to account for this difference by testing the typeof result and in the case of a legacy browser (such as Internet Explorer) manually parse the response. You may take a look at the source code of the page I have linked to.
But this being said, I can see that in your success callback you are redirecting to a controller action contained in the JSON response returned by the server. Here comes my question: What's the point of using AJAX in the first place if you are going to redirect? Why don't you use a standard form post to the controller action and have the controller action directly perform the redirect? AJAX should be used when you want to stay on the same page.
I agree with Jesse's comment, this is probably a duplicate of the link he provided.
As such I'll provide an alternative. I prefer to view json coming over the wire using a http proxy similar to fiddler http://www.fiddler2.com/fiddler2/ . I mention fiddler because it works with all browsers. The advantage is that you get a treeview of the parsed json. It's MUCH easier to read and find what you're looking for.
Also, I believe firebug for firefox, chrome dev tools, and ie dev tool all provide the same functionality. (I know chrome has the treeview, I think I remember firebug having it, and I would be surprised if modern IE doesn't have it considering the other 2 do.)

Is this possible through javascript?

I am currently working on asp.net project. I use oodle web service. Oodle provides result via URL. I use Link to get data from the URL.
From code behind I use following code to fetch the resultant string :
string url =
#"http://api.oodle.com/api/v2/listings?
key=TEST&region=chicago&category=vehicle&format=json";
var jsonString = new WebClient().DownloadString(url);
Now , My problem is I use button click event to run that code. But is this through JavaScript ? Because If I use Javascript it will be easier to access my resultant data.
It looks like this API returns JSONP which means that you could consume it directly from javascript. For example if you use jQuery you could use the $.ajax() method:
$.ajax({
url: 'http://api.oodle.com/api/v2/listings?key=TEST&region=chicago&category=vehicle&format=json',
type: 'GET',
dataType: 'jsonp',
jsonpCallback: 'jsonOodleApi',
success: function(result) {
alert(result.current.region.id);
}
});
Here's a live demo.
And if you don't use jQuery you could simply define a callback:
var jsonOodleApi = function(result) {
alert(result.current.region.id);
};
and then include a <script> pointing to this url:
<script type="text/javascript" src="http://api.oodle.com/api/v2/listings?key=TEST&region=chicago&category=vehicle&format=json"></script>
Here's a live demo.
Obviously you could inject this script tag dynamically into the DOM whenever you want to invoke the API call.
You can make Ajax requests to the page through Javascrypt.
here's a tutorial on that
If you are using some JavaScript frameworks, like JQuery, those requests would be easier to make, as the AJAX requests are kinda not cross-browser compatible.
the JQuery version
What you want is an AJAX request. It it certainly possibly to do without libraries, but due to crossbrowser issues I would recommend using a library. With jQuery for example it could look like this (in a document ready part of script):
$("#idOfButton").click(function() {
$.get('string url= #"http://api.oodle.com/api/v2/listings?key=TEST&region=chicago&category=vehicle&format=json', function(jsonString) {
alert('Data is now in variable jsonString!');
});
});

web request from the user browser

is it possible to send a web request from the user browser to another api and then process the result sent back??
im trying the following ajax code but its not working, i was wondering whether is it possible or not and if its a yes how can i implement it ...
$(document).ready(function() {
$.ajax({
type: "GET",
url: "http://api.ipinfodb.com/v2/ip_query.php?key=a9a2b0ec2c4724dd95286761777b09f1c8e82894de277a5b9d7175fa5275f2da&ip=&output=xml",
dataType: "xml",
success: function(xml) {
alert("sucess");
$(xml).find('Ip').each(function() {
var ip = $(this).find('Ip').text();
alert(ip);
});
}
});
});
Due to same origin policy restriction you are pretty limited to sending AJAX requests to your own domain only. JSONP is a common workaround but the remote site needs to support it. Another workaround consists in crating a server side script on your domain which will serve as a bridge between your domain and the remote domain and it will simply delegate the AJAX request sent to it from javascript.
Should be possible, I have done the same.
BUT you have to have the pages on the same server, you cannot send a request to another server, in that case you would have to use a proxy on your server to relay the call.
Just to add to what was already said: if you can't create your own JSONP proxy, you can use YQL service which creates that proxy for you. Note that YQL will wrap your data with it's own meta data (unless there is a way yo disable that...).
By the way, you should use JSON output instead of XML output from your API service. JSON is a more lightweight format and as such is more adapted for Web.
Below is a fully functional example with your API URL (outputting JSON this time) and YQL:
var apiRequestUrl = "http://api.ipinfodb.com/v2/ip_query.php?key=a9a2b0ec2c4724dd95286761777b09f1c8e82894de277a5b9d7175fa5275f2da&ip=&output=json";
var yqlRequestUrl = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%20%3D%20%22";
yqlRequestUrl += encodeURIComponent(apiRequestUrl);
yqlRequestUrl += "%22&format=json&callback=?";
$.getJSON(yqlRequestUrl,
function(jsonData) {
alert(jsonData.query.results.json.Ip);
});
Finally, this article can come handy: http://www.wait-till-i.com/2010/01/10/loading-external-content-with-ajax-using-jquery-and-yql/

Categories