Parsing RSS Feeds in JavaScript - Options

This post is more than 2 years old.

For a while now I've used the Google Feed API to parse RSS feeds in JavaScript. It did a good job of converting various RSS flavors into a simple array of entries you could easily work with. Unfortunately, Google has deprecated the API and while it still worked the last time I used it, I would strongly recommend folks migrate their apps away from it as soon as possible. While this makes me sad, you have to move on.

2000px-Sad_panda.svg

So what kind of options do you have?

Parsing Manually

So remember that RSS is just XML, and XML is just a string, and string parsing is easy, right? Of course, there are 2 major flavors of RSS, and multiple versions of both flavors, but if you're just parsing one known RSS feed then you can write to that particular flavor and version. (More about the different versions can be found on Wikipedia.) Unfortunately, if you try to simply XHR to a RSS feed you'll run into the lovely cross origin browser doohicky that prevents you from making requests to another server. Of course, if the RSS is on the same domain, that isn't a problem. And of course, if you are building something in Apache Cordova, then it isn't a problem either. (Just don't forget to update the CSP!) And finally - if you control the RSS, you could add a CORS header to it so modern browsers could use it. Unfortunately, if none of those apply, you're out of luck trying to do it completely client-side. (Well, until we get to the next options!) Let's pretend that none of the roadblocks apply to you and look at a simple example. (As a quick note, none of my sample code will actually render anything. It will just get crap, parse it, and log data. I'm assuming folks know how to manipulate the DOM. I've heard there's a good library for that.)

$(document).ready(function() {
	//feed to parse
	var feed = "http://feeds.feedburner.com/raymondcamdensblog?format=xml";
	
	$.ajax(feed, {
		accepts:{
			xml:"application/rss+xml"
		},
		dataType:"xml",
		success:function(data) {
			//Credit: http://stackoverflow.com/questions/10943544/how-to-parse-an-rss-feed-using-javascript

			$(data).find("item").each(function () { // or "item" or whatever suits your feed
				var el = $(this);
				console.log("------------------------");
				console.log("title      : " + el.find("title").text());
				console.log("link       : " + el.find("link").text());
				console.log("description: " + el.find("description").text());
			});
	

		}	
	});
	
});

So all I'm doing here is using jQuery to request my RSS feed. I then use jQuery's built in XML parsing to iterate over the <item> blocks in my RSS feed. As you can see, I'm using sample code from a StackOverflow answer that I modified a tiny bit. Specifically the answer iterated over <entry> blocks, not <item>. Remember when I said there were different flavors of RSS? That's an example of the issue right there. If you must write code to handle both cases, you would need to look for <item> first and then <entry>. But that's basically it. If your curious, I tested this in Canary with --disable-web-security as a command line flag.

shot1

YQL

Remember YQL (Yahoo Query Language)? The last time I blogged about it was way back in 2010 (Proof of Concept 911 Viewer). As a gross simplification, YQL acts like a "query language" for the web. You can literally run SQL like content against URLs and get formatted data out of it. They provide a powerful testing console and wouldn't you know it, one of the examples is a RSS parser:

shot2

Just in case that screenshot is a bit too small, here is what the YQL statement looks like:

select title from rss where url="http://rss.news.yahoo.com/rss/topstories"

I've got one word for that. Bad ass! Like, kitten in armor bad ass!

shot3

I tested with two different RSS flavors and YQL had no issue handling either. Note the REST query URL at the bottom. I copied that into a new file:

$(document).ready(function() {
	
	var yql = "https://query.yahooapis.com/v1/public/yql?q=select%20title%2Clink%2Cdescription%20from%20rss%20where%20url%3D%22http%3A%2F%2Ffeeds.feedburner.com%2Fraymondcamdensblog%3Fformat%3Dxml%22&format=json&diagnostics=true&callback=";
	
	$.getJSON(yql, function(res) {
		console.log(res);	
	}, "jsonp");
	
});

And it worked like a charm. Note the use of JSON/P to sidestep needing CORS. And here is the result:

shot4

A big thank you to Addy Osmani from Google for reminding me that YQL was still around. Google, I forgive you for killing the Feed API now.

Feednami

Last but not least is a brand new service, Feednami, created just in time for the death of the Google Feeds API. To use it you simply add a new script to your code and then use feednami.load() to get your feed. Here is an example:


$(document).ready(function() {
	
	var url = 'http://feeds.feedburner.com/raymondcamdensblog?format=xml';
	
	feednami.load(url,function(result){
		if(result.error) {
			console.log(result.error);
		} else {
			var entries = result.feed.entries;
			for(var i = 0; i < entries.length; i++){
				var entry = entries[i];
				console.dir(entry);
			}
		}
	});
	
});

That's also pretty darn easy to use. Here is the result:

shot5

Summary

So - you've got options. Which one is best? Honestly I don't know. YQL requires the least amount of code from what I can see, but I kinda dig Feednami's look a bit more. If you've used any of these in production, drop me a comment below with your thoughts!

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Julien posted on 12/11/2015 at 4:49 PM

Hey, I want to mention that there is also Superfeedr. We've been here for a couple years too.

The biggest difference with YQL i guess is that we charge for our API and that this is our core business... Free services from Google or Y! (remember Yahoo! Pipes?) always end up shut down at the expense of the ecosystem built around them, mainly because there's little incentive for them to keep them up in the long run.

Comment 2 by Андрей Балакирев posted on 12/11/2015 at 4:55 PM

Try Goose Parser, man! https://github.com/redco/go...

Comment 3 (In reply to #2) by Andrew Red posted on 12/11/2015 at 5:03 PM

Yeah! I've tried it. It's amazing one.

Comment 4 by Raymond Camden posted on 12/11/2015 at 5:09 PM

Thanks folks (below) for offering up even more options! :)

Comment 5 by wingi posted on 12/13/2015 at 8:47 PM

One big feature from google feed api is/was to search for all rss feed on one domain. Superfeedr has it on the feature list for 2016 ...

Comment 6 (In reply to #5) by Raymond Camden posted on 12/14/2015 at 2:12 PM

Is this something you would actually use though? It doesn't seem like something most folks would.

Comment 7 by Alan Houser posted on 12/14/2015 at 10:51 PM

I want to mention that the kitten in armor made my day— nay, my life.

Comment 8 (In reply to #7) by Raymond Camden posted on 12/15/2015 at 2:22 PM

If you see me post something without a kitten, check to ensure I've not been taken over by the pod people.

Comment 9 by Gary F posted on 12/19/2015 at 10:40 AM

A forum post from a Google employee last week said Google Feed is back up and running and they are yet to decide what to do with it. Seems nuts to drop a useful and self-running service. Can't cost them much to run. YQL seems like a good alternative. I tried to find out what their cache policy is, if there is a cache at all, but to no avail. Feednami is pretty cool (a drop-in replacement for Google Feed) but anyone relying on it to feed a production site/app is dependant on the developer keeping the back-end running. Maybe he could release the server code or as a cloud package for Google/Amazon. :-)

Comment 10 (In reply to #9) by Raymond Camden posted on 12/19/2015 at 4:11 PM

Got a link to that post?

To be honest - that pisses me off. If you are going to shut down a service, do so. Don't by wishy-washy.

Comment 11 (In reply to #10) by Gary F posted on 12/19/2015 at 4:37 PM

What annoys me is there isn't a termination date. A depreciation date is completely different. The date it switches off is far more useful than the date it begins to drag on and might or might not stop when someone feels like flipping the switch. Here's a link to the conversation. Read John's first post (Dec 5) and then scroll down to his second one on 8th. https://developers.google.c...

BTW, I think YQL has a caching issue? A Y! blog says to add _maxage=3600 as a URL parameter but my server still logs every single hit from Y! It's user agent string is YahooCacheSystem.

Comment 12 (In reply to #11) by Raymond Camden posted on 12/20/2015 at 4:36 AM

Sounds like something to report to Yahoo.

Comment 13 by Kelvin Shadewing posted on 2/21/2016 at 11:21 PM

Using the first example, I keep getting a "not well-formed" error, and the console can't even tell me where the error is or what it means. Do you have any idea what it's talking about?

Comment 14 (In reply to #13) by Raymond Camden posted on 2/21/2016 at 11:53 PM

Did you run into the cross domain issue?

Comment 15 (In reply to #13) by Raymond Camden posted on 2/21/2016 at 11:55 PM

I just retested my code locally (using a copy of the XML feed also locally) and it worked fine.

Comment 16 (In reply to #14) by Kelvin Shadewing posted on 2/22/2016 at 12:04 AM

No, the code's on the same server as the file. The logging works, but I'm just confused about what Firefox means by not well-formed.

I dunno, maybe it's just complaining because I use C++ layout style and JavaScript, in most examples I've seen, uses a layout akin to C#, so maybe it's just saying I'm unconventional?

Either way, it's a good example. I can easily change the output so that it adds HTML to my site. Thanks a bunch for this. 0.-.<

Comment 17 (In reply to #16) by Raymond Camden posted on 2/22/2016 at 12:05 AM

No worries!

Comment 18 (In reply to #17) by Kelvin Shadewing posted on 2/22/2016 at 5:10 PM

Oh, something you should probably mention in the tutorial, I figured this out when trying to fix my own news feed because it kept disappearing. Sometimes, using the full URL, including the domain name and such, causes it to fail, so the success function is never even run. I changed mine from "kelvinshadewing.net/feed.xml" to just "feed.xml" and now it works perfectly for me. (Assuming you didn't already mention that, since I didn't re-read it, heheh.)

Comment 19 by RastaPopuloS posted on 4/11/2016 at 7:51 AM

How can we get rss feeds directly from a website on the net without getting any error like
"XMLHttpRequest cannot load "aSiteOnTheWeb". Origin null is not allowed by Access-Control-Allow-Origin. " ? ty
*Sry for my bad english tho

Comment 20 (In reply to #19) by Raymond Camden posted on 4/11/2016 at 1:02 PM

You can't - unless the remote server is using CORS to serve the RSS. It is a browser security issue.

Comment 21 (In reply to #20) by RastaPopuloS posted on 4/11/2016 at 1:27 PM

Ok, thanks. :)
So How shall I retrieve news dynamically from "The Guardian" for example and put it on my website ? :/

Comment 22 (In reply to #21) by Raymond Camden posted on 4/11/2016 at 1:57 PM

Err... follow what I said in this blog post?

Comment 23 (In reply to #22) by RastaPopuloS posted on 4/11/2016 at 2:23 PM

I followed the first example. When i try with a local xml file, it works. But when i try with an xml file on the web, Chrome send me the error i gave above. And sadly, I don't know why...

Comment 24 (In reply to #23) by Raymond Camden posted on 4/11/2016 at 2:30 PM

I hate to be rude - but you really need to *read* the blog post. The first option *specifically* points out it has to be local. You do see that, right? That's why I discuss the other options.

Comment 25 (In reply to #24) by RastaPopuloS posted on 4/11/2016 at 2:58 PM

Oh you're right ! I'm so sorry, next time i'll reread all the article before posting a comment ! My english is so bad ( i'm french ) and i think i didn't understand all that you wrote. Fortunately you answered me fast, thank you :)

Comment 26 (In reply to #25) by Raymond Camden posted on 4/11/2016 at 3:01 PM

No problem and glad you got it. Au revoir!

Comment 27 (In reply to #20) by Pixel & Kraft posted on 5/31/2016 at 8:25 AM

You can use a CORS proxy, such as https://crossorigin.me/

Comment 28 by Simon Grimm posted on 7/2/2016 at 6:27 PM

Sorry for asking on this old post, but do you know how to get more than 10 results using YQL?

Comment 29 (In reply to #28) by Raymond Camden posted on 7/4/2016 at 12:02 AM

Does the RSS feed your parsing have more than 10 items?

Comment 30 (In reply to #29) by Simon Grimm posted on 7/4/2016 at 4:21 AM

Haha good point.. Yeah I guess there are only 10 items. And seems like loading older stuff is not really supported, so thanks anyway!

Comment 31 by Francis Kim posted on 11/23/2016 at 11:42 PM

Thanks for the post! Very relevant to what I'm doing right now.

Comment 32 (In reply to #31) by Raymond Camden posted on 11/24/2016 at 4:46 PM

You are most welcome.

Comment 33 by Abu Nj posted on 8/30/2017 at 2:55 PM

YQL stopped working or inconsistent

Comment 34 (In reply to #33) by Raymond Camden posted on 8/30/2017 at 3:10 PM

Seems to be working ok for me - but all I did was test the URL I used in the demo above.

Comment 35 by NiftyToolz posted on 8/30/2017 at 8:34 PM

YQL is intermittently down - use the YQL console with diagnostics ticked (I think that prevents caching). It's been up and down like a yo-yo since last Thursday morning (EST). More down than up.

Comment 36 (In reply to #33) by Chris posted on 9/4/2017 at 9:53 PM

I have the same issue with YQL. You get a result, if you are lucky - or not.

Comment 37 (In reply to #36) by Abu Nj posted on 9/5/2017 at 3:49 PM

yes, yql rss feed become inconsistent

Comment 38 by Gopi Krishna posted on 9/28/2017 at 5:10 AM

I get the below pasted error while i try extracting rss from "http://timesofindia.indiati...". Can you please help me in resolving this issue?

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access

Comment 39 (In reply to #38) by Raymond Camden posted on 9/28/2017 at 1:03 PM

Yes, that's covered in my first suggestion. I didn't specify the error though so I apologize, but that's what your running into. You need to use one of the other suggestions.

Comment 40 by siddharth posted on 10/4/2017 at 9:49 AM

there is a descrption tag in money control http://www.moneycontrol.com...
from description tag i want only image..how to do this

Comment 41 (In reply to #40) by Raymond Camden posted on 10/4/2017 at 1:20 PM

Well it's in the XML. You can extract it using XML parsing in JavaScript. What did you try?

Comment 42 (In reply to #41) by siddharth posted on 10/5/2017 at 12:05 PM

i have used that its working fine.i have parsed var feed = "http://www.moneycontrol.com..."|; but instead of this if i am using some other link like "http://profit.ndtv.com";its throwing error like
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access..can u help me...i want multipe feed to be call.
my code is like this:

var a=[];

$(document).ready(function() {
//feed to parse
var feed = "http://profit.ndtv.com";

$.ajax(feed, {
accepts:{
xml:"application/rss+xml"
},
dataType:"xml",
success:function(data) {

$(data).find("item").each(function () {
var el = $(this);

title = el.find("title").text();
link = el.find("link").text();
string = el.find("description").text();
stringarr = string.split(">");
img = stringarr[0]+">";
//formated2 = "" + title + "
" + link +"
" + img + "


"
formated1 = " " + title + "
" + img + "


"
hello(formated1)

});

}
});

});

function hello(data)
{

a.push(data);
var r=document.getElementById('news');
r.innerHTML=a;
}

</script>

Comment 43 (In reply to #42) by Raymond Camden posted on 10/5/2017 at 12:42 PM

That's the CORS issue I mentioned in the first part of the blog post.

Comment 44 by Sarower Jahan posted on 7/14/2018 at 12:14 AM

Great solution. thanks

Comment 45 by Waiyee Lai posted on 1/9/2019 at 4:11 PM

Starting this year, 2019, the YQL stops working. I am in need of a javascript rss reader replacement.

Comment 46 (In reply to #45) by Raymond Camden posted on 1/9/2019 at 4:39 PM

Did you try the other two suggestions?

Comment 47 by Sam posted on 1/27/2019 at 7:38 AM

Feednami isn't working in hosted site but works fine in local. It says 403 forbidden -Hostname in referer header is not registered.

Is there a way to fix it?

Comment 48 (In reply to #47) by Raymond Camden posted on 1/29/2019 at 2:32 PM

Did you register the hostname? https://toolkit.sekando.com...