I. Introduction
Now, developing an RSS aggregator is no longer difficult, but developing a high-quality RSS aggregator is still quite difficult. On the other hand, it is generally not difficult to create a custom aggregator, And you can provide an interface of your choice in this aggregator. RSS aggregation represents a type of data that is especially suitable for consumption by an AJAX application, because it is in XML format and AJAX can display new feedback well without page refreshing. However, the problem always exists: it is impossible to implement cross-origin AJAX requests in a standard AJAX engine. In this article, I will show you how to use a simple PHP function to bridge AJAX engines and remote content (in this article it refers to RSS feedback ).
Ii. Start
Before we officially start, I would like to briefly introduce the AJAX engine we will use to send requests. The engine simplifies AJAX calls and helps eliminate a large number of redundancy when requests are sent and scheduled. I will not discuss its composition code in detail, but will only give you a brief introduction to how we use it in this article.
First, we need to import all the JavaScript files that constitute the engine. The Code included in our index.html file looks as follows:
<script type="text/javascript" src="js/model/HTTP.js"></script> <script type="text/javascript" src="js/model/Ajax.js"></script> <script type="text/javascript" src="js/model/AjaxUpdater.js"></script>
|
Once we import the JavaScript file, we can send a request by writing code similar to the following:
AjaxUpdater.Update('GET', 'url',callbackMethod);">
|
The AjaxUpdater is an object that processes our AJAX calls. We simply call its Update method and pass the requested method, the URL of our request, and the callback method we want to delegate the response.
When sending our request, this is all we need to care about. Now, let's focus on customizing the RSS aggregator function.
Iii. Entry Point
It refers to the file index.html, which we call from the browser. The following code describes the index:
<html> <head> <title>RSS Aggregation with PHP and Ajax</title> <link href="css/layout.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/model/HTTP.js"></script> <script type="text/javascript" src="js/model/Ajax.js"></script> <script type="text/javascript" src="js/model/AjaxUpdater.js"></script> <script type="text/javascript" src="js/controller/Aggregator.js"></script> <script type="text/javascript" src="js/view/Feed.js"></script> </head> <body> <div id="Aggregator"> <form name="feedForm" method="post" action="javascript:AjaxUpdater.Update('GET', 'bridge/rss.php?feed=' + document.feedForm.feed.value, Aggregator.Read);"> <div class="header"> <input type="text" name="feed" id="feed" size="50"> <input type="submit" name="submit" value="Add Feed"> </div> </form> <div class="leftColumn"> <div id="titles"></div> <div id="loading"></div> </div> <div class="rightColumn"> <div id="description"></div> </div> </div> </body> </html>
|
This file is responsible for importing and processing the CSS file displayed by our aggregator and all the JavaScript files used to create the aggregator and send AJAX requests.
Tip: This document does not discuss the CSS file. We only focus on the aggregation and analysis through JavaScript.
Then, the index defines the DIV tag, which will be used to describe the layout of the received data. It also contains a form with an input field used to enter the URL for RSS feedback and a submit button used to send requests to them. When you click this button, a request is sent to receive RSS feedback and the response is sent to an object called Aggregator; we will introduce it after discussing the use of AJAX technology for remote RSS feedback retrieval.
4. Cross-origin AJAX requests
Cross-origin AJAX requests are impossible, but there are some methods to solve this problem using a server language. In this section, I will discuss how to use PHP to create a bridge between an AJAX request and a remote RSS feed, so as to successfully implement cross-origin requests. I think you may be surprised at its easy implementation.
PHP provides a local method called file_get_contents, which can read the entire file content into a string. If you start the fopen package, this file can be a remote file, which is started by default when you install PHP. If you set allow_url_fopen to off in the php. ini file, it will be disabled. The following code corresponds to the content of the bridge.php file. When submitting a ticket, we use index.html to send the request:
<? header("Content-Type: application/xml; charset=UTF-8"); echo file_get_contents($_GET['feed']); ?>
|
The first line in the code above is a header, which is responsible for setting the response content type to a valid XML for our request object. Then, call file_get_contents and combine the feed url-to pass the request from the form in the index.html file. Once the data is ready, the AJAX engine proxies them to the callback method-our Aggregator object.
5. Aggregator object
The Aggregator object receives responses from the AJAX engine. Callback method of the request sent in the callback form ). When this callback occurs, use a custom AJAX object method (which uses a string that describes the DIV element that loads the message as a parameter) to check the requested readyState.
Aggregator = new Object(); Aggregator.feedCollection = new Array(); Aggregator.Read = function() { if(Ajax.checkReadyState('loading') == "OK") { var title = Ajax.getResponse().getElementsByTagName('title')[0].firstChild.data; var _link = Ajax.getResponse().getElementsByTagName('link')[0].firstChild.data; var items = Ajax.getResponse().getElementsByTagName('item'); var feed = new Feed(Aggregator.feedCollection.length, title, _link, items); Aggregator.feedCollection.push(feed); Aggregator.displayFeedTitles(feed); } }
|
In this Read method, the first thing we need to do is to analyze the title, links, and items in the RSS feedback. Once we have these values, we can create a new Feed object (which will be discussed later ). This object uses the length of feedCollection (as an ID), as well as the title, link, and items from feedback. The Feed object is then added to the feedCollection and a method called displayFeedTitles to display the title corresponding to each item in the Feed object.
Aggregator.displayFeedTitles = function(feed) { document.getElementById('titles').innerHTML += feed.GetTitle(); Aggregator.DisplayTitles(feed.id); }
|
This method uses the Feed object as a parameter, displays its title, and then calls another method called DisplayTitles:
Aggregator.DisplayTitles = function(id) { var titleArray = Aggregator.feedCollection[id].GetAllTitles(); var titles = document.createElement("div"); titles.id = "subTitle_"+ id; document.getElementById('title_'+id).appendChild(titles); for(var i=0; i<titleArray.length; i++) { titles.innerHTML += titleArray[i] +"<br />"; } }
|
This method receives a feedback ID and uses it to retrieve feedback from the feedCollection array and obtain all its headers. Once these titles are received, we will create a new DIV element for the title of the item in the feedback and add it after the title corresponding to the specific feedback. This allows us to switch the title of the item in the displayed content by clicking the feedback title. Once the new DIV element is added, we simply need to traverse all the headers and add them to the new DIV.
The first of the two statements is used to switch the items in the feed. The second statement is responsible for displaying the feedback content in the index.html file that describes the DIV element. The feedback content is collected through the GetDetails method of the Feed object (discussed later in the next section when we create the Feed object ).
Aggregator.ToggleTitles = function(id) { var titles = document.getElementById('subTitle_'+id); titles.style.display = (titles.style.display == '') ? 'none' : ''; } Aggregator.DisplayFeed = function(feedId, id) { var details = Aggregator.feedCollection[feedId].GetDetails(id); document.getElementById('description').innerHTML = details; }
|
6. Feed object
This Feed object is a prototype. Through its constructor function, the Feed object receives all the parameters passed when we create it in the Aggregator object. These parameters correspond to the feedback ID, title, link, and item respectively. In this function, we set all the default values, create some Arrays for future use, and send the items to a method called parseItems. In this parseItems method, we will retrieve all the values in our feedback items and fill in the array we created in the constructor.
Feed.prototype.parseItems = function(items) { for(var i=0; i<items.length; i++) { var linkTitle = items[i].getElementsByTagName("title")[0].firstChild.nodeValue; var title = "<a href="#' class='title' onclick='Aggregator.DisplayFeed("+ this.id +", "+ i +");'>" + linkTitle +"</a>"; this.titleArray.push(title); this.linkTitleArray.push(linkTitle); var _link = items[i].getElementsByTagName("link")[0].firstChild.nodeValue; this.linkArray.push(_link); var description = items[i].getElementsByTagName("description")[0].firstChild.nodeValue; this.descriptionArray.push(description); var pubDate = items[i].getElementsByTagName("pubDate")[0].firstChild.nodeValue; this.pubDateArray.push(pubDate); } }
|
Once we store all the values in an array, we can use them when we are ready to display the data in the page. The third method in this object focuses on displaying data in feedback:
◆ GetTitle is responsible for obtaining the feedback title (as a link to the switch item title, it is implemented by calling the toggleTitles method of Aggregator ).
◆ GetAllTitles returns all item titles from feedback.
◆ GetDetails is responsible for displaying all the details of the feedback. This method retrieves the value in the array of the Feed object based on the ID passed as a parameter. These values are then formatted into an HTML string and returned to the caller. Then, the caller adds them to the index page.
Feed.prototype.GetTitle = function() { return "<div id='title_"+ this.id +"'><br/><a href='#' onclick='Aggregator.ToggleTitles("+ this.id +");'>" + this.title + "</a></div>"; } Feed.prototype.GetAllTitles = function() { return this.titleArray; } Feed.prototype.GetDetails = function(id) { details = "<a href='"+ this.linkArray[id] +"' target='_blank'>"+ this.linkTitleArray[id] +"</a><br/>"; details += this.descriptionArray[id] +"<br/>"; details += this.pubDateArray[id]; return details; }
|
VII. Summary
So far, the next step for the Aggregator object created above should be to add a timeout to check the updates to the RSS feedback currently added to the Aggregator. In addition, the feedback can be saved to a database and retrieved based on the user account. However, due to space limitations, these functions have to be implemented by the reader.
(Responsible editor: Ming