apache traffic server interpret via header,how to decode this code by myself - apache-traffic-server

{ server: 'ATS/5.0.1',
date: 'Thu, 04 Sep 2014 05:34:16 GMT',
'content-type': 'image/jpeg',
'content-length': '47265',
'last-modified': 'Sat, 09 Aug 2014 07:32:06 GMT',
expires: 'Mon, 25 Aug 2014 06:45:37 GMT',
'cache-control': 'max-age=604800',
'load-balancing': 'web39',
'x-cache-status': 'HIT',
'accept-ranges': 'bytes',
age: '94784',
connection: 'keep-alive',
via: 'http/1.1 upyun (ApacheTrafficServer/5.0.1 [cHs f ])'
}
The ATS protocol-encoded field ("cHs f") can be decoded at http://trafficserver.apache.org/tools/via
What should be done to decode it locally, on my server?
Is there any description of the encode-protocol?
Having the encode-protocol definition, I can decode it myself.

var codes = {}
codes[1] = {}
codes[1]['title'] = "client-info Request headers received from client. Value is one of:"
codes[1]['I'] = "If Modified Since (IMS)"
codes[1]['C'] = "cookie"
codes[1]['E'] = "error in request"
codes[1]['S'] = "simple request (not conditional)"
codes[1]['N'] = "no-cache"
codes[2] = {}
codes[2]['title'] = "cache-lookup Result of Traffic Server cache lookup for URL. Value is one of:"
codes[2]['A'] = "in cache, not acceptable (a cache \"MISS\")"
codes[2]['H'] = "in cache, fresh (a cache \"HIT\")"
codes[2]['S'] = "in cache, stale (a cache \"MISS\")"
codes[2]['R'] = "in cache, fresh Ram hit (a cache \"HIT\")"
codes[2]['M'] = "miss (a cache \"MISS\")"
codes[2][' '] = "no cache lookup performed"
codes[3] = {}
codes[3]['title'] = "server-info Response information received from origin server. Value is one of:"
codes[3]['E'] = "error in response"
codes[3][' '] = "no server connection needed"
codes[3]['S'] = "served"
codes[3]['N'] = "not-modified"
codes[4] = {}
codes[4]['title'] = "cache-fill Result of document write to cache. Value is one of:"
codes[4]['U'] = "updated old cache copy"
codes[4]['D'] = "cached copy deleted"
codes[4]['W'] = "written into cache (new copy)"
codes[4][' '] = "no cache write performed"
codes[5] = {}
codes[5]['title'] = "proxy-info Proxy operation result. Value is one of:"
codes[5]['R'] = "origin server revalidated"
codes[5][' '] = "unknown?"
codes[5]['S'] = "served"
codes[5]['N'] = "not-modified"
codes[6] = {}
codes[6]['title'] = "error-codes Value is one of:"
codes[6]['A'] = "authorization failure"
codes[6]['H'] = "header syntax unacceptable"
codes[6]['C'] = "connection to server failed"
codes[6]['T'] = "connection timed out"
codes[6]['S'] = "server related error"
codes[6]['D'] = "dns failure"
codes[6]['N'] = "no error"
codes[6]['F'] = "request forbidden"
codes[7] = {}
codes[7]['title'] = "tunnel-info Proxy-only service operation. Value is one of:"
codes[7][' '] = "no tunneling"
codes[7]['U'] = "tunneling because of url (url suggests dynamic content)"
codes[7]['M'] = "tunneling due to a method (e.g. CONNECT)"
codes[7]['O'] = "tunneling because cache is turned off"
codes[7]['F'] = "tunneling due to a header field (such as presence of If-Range header)"
codes[8] = {}
codes[8]['title'] = "cache-type and cache-lookup cache result values (2 characters)"
codes[8]['I'] = "icp"
codes[8][' '] = "cache miss or no cache lookup"
codes[8]['C'] = "cache"
codes[9] = {}
codes[9]['title'] = "cache-lookup-result character value is one of:"
codes[9][' '] = "no cache lookup"
codes[9]['S'] = "cache hit, but expired"
codes[9]['U'] = "cache hit, but client forces revalidate (e.g. Pragma: no-cache)"
codes[9]['D'] = "cache hit, but method forces revalidated (e.g. ftp, not anonymous)"
codes[9]['I'] = "conditional miss (client sent conditional, fresh in cache, returned 412)"
codes[9]['H'] = "cache hit"
codes[9]['M'] = "cache miss (url not in cache)"
codes[9]['C'] = "cache hit, but config forces revalidate"
codes[9]['N'] = "conditional hit (client sent conditional, doc fresh in cache, returned 304)"
codes[10] = {}
codes[10]['title'] = "icp-conn-info ICP status"
codes[10][' '] = "no icp"
codes[10]['S'] = "connection opened successfully"
codes[10]['F'] = "connection open failed"
codes[11] = {}
codes[11]['title'] = "parent-proxy parent proxy connection status"
codes[11][' '] = "no parent proxy"
codes[11]['S'] = "connection opened successfully"
codes[11]['F'] = "connection open failed"
codes[12] = {}
codes[12]['title'] = "server-conn-info origin server connection status"
codes[12][' '] = "no server connection"
codes[12]['S'] = "connection opened successfully"
codes[12]['F'] = "connection open failed"
function showVia(form, value) {
var text = value? value : form.via.value;
if (value) {
document.getElementById("via").value = value;
}
var via = document.getElementById("viaoutput")
var output = "";
var txtonly = text.match(/([a-zA-Z: ]+)/);
text = txtonly[1];
if (text.length == 5) {
text = text + " "
}
if (text.length == 24) {
var arr = text.match(/([a-zA-Z ]+):([a-zA-Z ]+)/);
output = output + "<h3>Proxy request results:</h3>";
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Request headers received from client:</div> <font color="#003399">' + codes[1][arr[1][1]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Result of Traffic Server cache lookup for URL:</div> <font color="#003399">' + codes[2][arr[1][3]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Response information received from origin server:</div> <font color="#003399">' + codes[3][arr[1][5]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Result of document write-to-cache:</div> <font color="#003399">' + codes[4][arr[1][7]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Proxy operation result:</div> <font color="#003399">' + codes[5][arr[1][9]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Error codes (if any):</div> <font color="#003399">' + codes[6][arr[1][11]] + '</font><br/>';
output = output + "<h3>Operational results:</h3>";
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Tunnel info:</div> <font color="#003399">' + codes[7][arr[2][1]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Cache-type and cache-lookup cache result values:</div> <font color="#003399">' + codes[8][arr[2][3]] + " / " + codes[9][arr[2][4]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">ICP status:</div> <font color="#003399">' + codes[10][arr[2][6]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Parent proxy connection status:</div> <font color="#003399">' + codes[11][arr[2][8]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Origin server connection status:</div> <font color="#003399">' + codes[12][arr[2][10]] + '</font><br/>';
} else if (text.length == 6) {
output = output + "<h3>Proxy request results:</h3>";
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Result of Traffic Server cache lookup for URL:</div> <font color="#003399">' + codes[2][text[1]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Response information received from origin server:</div> <font color="#003399">' + codes[3][text[3]] + '</font><br/>';
output = output + '<div style="width: 450px; font-weight: bold; float: left;">Result of document write-to-cache:</div> <font color="#003399">' + codes[4][text[5]] + '</font><br/>';
} else {
output = "Invalid VIA data, must be 24 or 6 characters long.";
}
via.innerHTML = output;
if (form) {
window.location.hash = escape(text);
}
return false;
}
function checkQuery() {
var url = location.href;
if (url.indexOf("#") > 0) {
var qs = url.substring(url.indexOf("#")+1).replace("%20", " ").replace("+", " ");
if (qs && qs.length > 5) {
showVia(false, qs);
}
}
}

As of v5.3.0 (I think), there's a new command line utility, traffic_via, which decodes this header. E.g.
% traffic_via '[cHs f ]'
Via header is [cHs f ], Length is 8
Via Header Details:
Result of Traffic Server cache lookup for URL :in cache, fresh (a cache "HIT")
Response information received from origin server :no server connection needed
Result of document write-to-cache: :no cache write performed

Related

Debugging a jQuery plugin to display a dynamic list in two equal columns

I am trying to implement a jQuery plugin. The code is available on jsFiddle. http://jsfiddle.net/MKL4g/1/ but I have also copied my modifications below.
var postsArr = new Array(),
$postsList = $('div.cat-children ul');
//Create array of all posts in lists
$postsList.find('li').each(function(){
postsArr.push($(this).html());
})
//Split the array at this point. The original array is altered.
var firstList = postsArr.splice(0, Math.round(postsArr.length / 2)),
secondList = postsArr,
ListHTML = '';
function createHTML(list){
ListHTML = '';
for (var i = 0; i < list.length; i++) {
ListHTML += '<li>' + list[i] + '</li>'
};
}
//Generate HTML for first list
createHTML(firstList);
$postsList.html(ListHTML);
//Generate HTML for second list
createHTML(secondList);
//Create new list after original one
$postsList.after('<ul class="cat-list"></ul>').next().html(ListHTML);
I am implementing this on a Joomla 3.0.2 site using the Gantry 4.1.5 Framework.
The CSS to style the resulting UL LI array is as follows (LESS Format):
body {
&.menu-face-à-la-crise,
&.menu-divorce-séparation,
&.menu-études-de-cas,
&.menu-effets-de-la-vie-séparée,
&.menu-effets-du-divorce,
&.menu-effets-communs,
&.menu-situations-particulières,
&.menu-formulaires-modèles,
&.menu-suppléments-addendas,
&.menu-à-propos-de-nous {
div#rt-mainbody-surround {
margin-top: -1px;
background: #whitebrown;
}
div.component-content {
.blog {
li {
text-align: center;
font-family: #headingFontFamily;
font-weight: 700;
font-size: 2.0em;
line-height: 1.5em;
text-shadow: 1px 1px 1px rgba(0,0,0,0.3);
}
div.cat-children {
ul {
float: left;
padding: 10px;
}
}
}
}
}
}
I get the following error in the console:
TypeError: 'null' is not an object (evaluating '$postsList.find')
You can see the implementation here:
http://gobet.ergonomiq.net/études-de-cas/effets-du-divorce
As you can see, it doesn't seem to take the list items and split them into two columns.
The resulting display should split the list into two columns, and have the list items be visually centred to the columns.
Can someone advise how to debug and resolve this?
You have MooTools enabled and at the beginning of your script. Flip it so that you're using the jQuery selectors.
var postsArr = [],
$postsList = jQuery('.cat-children ul');
//Create array of all posts in lists
$postsList.find('li').each(function(){
postsArr.push(jQuery(this).html());
})
//Split the array at this point. The original array is altered.
var firstList = postsArr.splice(0, Math.round(postsArr.length / 2)),
secondList = postsArr,
ListHTML = '';
function createHTML(list){
ListHTML = '';
for (var i = 0; i < list.length; i++) {
ListHTML += '<li>' + list[i] + '</li>'
};
}
//Generate HTML for first list
createHTML(firstList);
$postsList.html(ListHTML);
//Generate HTML for second list
createHTML(secondList);
//Create new list after original one
$postsList.after('<ul class="cat-list"></ul>').next().html(ListHTML);
edit for the new request
(function updateColumns($){
var postsArr = [],
$postsList = $('.cat-children ul'),
$parent = $postsList.parent();
//Create array of all posts in lists
$postsList.find('li').each(function(){
postsArr.push(jQuery(this).html());
})
//Split the array at this point. The original array is altered.
var firstList = postsArr.splice(0, Math.round(postsArr.length / 2)),
secondList = postsArr,
// ListHTML = '', <-- not needed
$insertWrapper = $('<div>').addClass('cat-children');
function createHTML(list){
var $ul = $('<ul>').addClass('cat-list');
for (var i = 0; i < list.length; i++) {
$ul.append( $('<li>').html( $(list[i]).html() ) );
};
var $wrappedDiv = $('<div>').addClass('gantry-width-50 cat-columns').append( $ul )
return $wrappedDiv;
}
//Generate HTML for first list
$insertWrapper.append( createHTML(firstList) );
$insertWrapper.append( createHTML(secondList) );
$postsList.replaceWith( $insertWrapper );
})(window.jQuery);

HTML5 video from MVC3 action not working correctly

I'm serving video from an MVC3 site, with the controller action that returns the video returning a FilePathResult, and when trying to play back in the browser, I'm seeing some frustrating issues, regardless of my using video.js or mediaelement.js.
Chrome doesn't let you change the position using progressbar, nor does it allow you to replay the video once it has completed
IE9 seems relatively fine
Firefox doesn't show the elapsed/remaining time correctly
However, if I just give a relative path to the file being hosted, it all works fine.
The videos need to be available only to users who belong to certain roles, so that isn't really an option.
The Action:
[Authorize]
public ActionResult Video(string fileName)
{
var pathBase = Server.MapPath("~/Downloads/Videos/");
var filePath = pathBase + fileName;
var contentType = ContentType(fileName);
return new FilePathResult(filePath, contentType) { FileDownloadName = fileName };
}
The Razor:
<!-- #t = the video entity -->
<video width="640" height="360" id="#t.Id" poster="#Url.Action("Video", "Download", new { fileName = #t.Poster })" controls="controls" preload="none">
<!-- MP4 source must come first for iOS -->
<source src="#Url.Action("Video", "Download", new { fileName = #t.Mp4 })" type='video/mp4' />
<!-- WebM for Firefox 4 and Opera -->
<source src="#Url.Action("Video", "Download", new { fileName = #t.WebM })" type='video/webm' />
<!-- OGG for Firefox 3 -->
<source src="#Url.Action("Video", "Download", new { fileName = #t.Ogv })" type='video/ogg' />
<!-- Fallback flash player for no-HTML5 browsers with JavaScript turned off -->
<object width="640" height="360" type="application/x-shockwave-flash" data="#Url.Content("~/Content/flashmediaelement.swf")">
<param name="movie" value="#Url.Content("~/Content/flashmediaelement.swf")" />
<param name="flashvars" value="controls=true&poster=#Url.Action("Video", "Download", new { fileName = #t.Poster })&file=#Url.Action("Video", "Download", new { fileName = #t.Mp4 })" />
<!-- Image fall back for non-HTML5 browser with JavaScript turned off and no Flash player installed -->
<img src="#Url.Action("Video", "Download", new { fileName = #t.Poster })" width="640" height="360" alt="#t.Title"
title="No video playback capabilities" />
</object>
</video>
I ended up writing an HTTP Handler to deal with these extensions, though it seems Chrome's issue is to do with my handler not supporting Range requests.
I used the following blog post to help me out: http://blogs.visigo.com/chriscoulson/easy-handling-of-http-range-requests-in-asp-net/. The solution (modified by me to include content type, as well as some basic security) is as follows:
public void ProcessRequest(HttpContext context)
{
if (!context.Request.RequestContext.HttpContext.User.Identity.IsAuthenticated)
context.Response.Redirect("~");
var path =
context.Request.RequestContext.HttpContext.Server.MapPath(
context.Request.AppRelativeCurrentExecutionFilePath);
long size, start, end, length, fp = 0;
using (StreamReader reader = new StreamReader(path))
{
size = reader.BaseStream.Length;
start = 0;
end = size - 1;
length = size;
// Now that we've gotten so far without errors we send the accept range header
/* At the moment we only support single ranges.
* Multiple ranges requires some more work to ensure it works correctly
* and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
*
* Multirange support annouces itself with:
* header('Accept-Ranges: bytes');
*
* Multirange content must be sent with multipart/byteranges mediatype,
* (mediatype = mimetype)
* as well as a boundry header to indicate the various chunks of data.
*/
context.Response.AddHeader("Accept-Ranges", "0-" + size);
context.Response.ContentType = "video/mp4";
// header('Accept-Ranges: bytes');
// multipart/byteranges
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
{
long anotherStart = start;
long anotherEnd = end;
string[] arr_split =
context.Request.ServerVariables["HTTP_RANGE"].Split(new char[] {Convert.ToChar("=")});
string range = arr_split[1];
// Make sure the client hasn't sent us a multibyte range
if (range.IndexOf(",") > -1)
{
// (?) Shoud this be issued here, or should the first
// range be used? Or should the header be ignored and
// we output the whole content?
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
// If the range starts with an '-' we start from the beginning
// If not, we forward the file pointer
// And make sure to get the end byte if spesified
if (range.StartsWith("-"))
{
// The n-number of the last bytes is requested
anotherStart = size - Convert.ToInt64(range.Substring(1));
}
else
{
arr_split = range.Split(new char[] {Convert.ToChar("-")});
anotherStart = Convert.ToInt64(arr_split[0]);
long temp = 0;
anotherEnd = (arr_split.Length > 1 && Int64.TryParse(arr_split[1].ToString(), out temp))
? Convert.ToInt64(arr_split[1])
: size;
}
/* Check the range and make sure it's treated according to the specs.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
*/
// End bytes can not be larger than $end.
anotherEnd = (anotherEnd > end) ? end : anotherEnd;
// Validate the requested range and return an error if it's not correct.
if (anotherStart > anotherEnd || anotherStart > size - 1 || anotherEnd >= size)
{
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
start = anotherStart;
end = anotherEnd;
length = end - start + 1; // Calculate new content length
fp = reader.BaseStream.Seek(start, SeekOrigin.Begin);
context.Response.StatusCode = 206;
}
}
// Notify the client the byte range we'll be outputting
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
context.Response.AddHeader("Content-Length", length.ToString());
// Start buffered download
context.Response.WriteFile(path, fp, length);
context.Response.Flush();
}
Thanks for your answer!
I used something similar:
internal static void StreamVideo(string fullpath, HttpContextBase context)
{
long size, start, end, length, fp = 0;
using (StreamReader reader = new StreamReader(fullpath))
{
size = reader.BaseStream.Length;
start = 0;
end = size - 1;
length = size;
// Now that we've gotten so far without errors we send the accept range header
/* At the moment we only support single ranges.
* Multiple ranges requires some more work to ensure it works correctly
* and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
*
* Multirange support annouces itself with:
* header('Accept-Ranges: bytes');
*
* Multirange content must be sent with multipart/byteranges mediatype,
* (mediatype = mimetype)
* as well as a boundry header to indicate the various chunks of data.
*/
context.Response.AddHeader("Accept-Ranges", "0-" + size);
// header('Accept-Ranges: bytes');
// multipart/byteranges
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
{
long anotherStart = start;
long anotherEnd = end;
string[] arr_split = context.Request.ServerVariables["HTTP_RANGE"].Split(new char[] { Convert.ToChar("=") });
string range = arr_split[1];
// Make sure the client hasn't sent us a multibyte range
if (range.IndexOf(",") > -1)
{
// (?) Shoud this be issued here, or should the first
// range be used? Or should the header be ignored and
// we output the whole content?
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
// If the range starts with an '-' we start from the beginning
// If not, we forward the file pointer
// And make sure to get the end byte if spesified
if (range.StartsWith("-"))
{
// The n-number of the last bytes is requested
anotherStart = size - Convert.ToInt64(range.Substring(1));
}
else
{
arr_split = range.Split(new char[] { Convert.ToChar("-") });
anotherStart = Convert.ToInt64(arr_split[0]);
long temp = 0;
anotherEnd = (arr_split.Length > 1 && Int64.TryParse(arr_split[1].ToString(), out temp)) ? Convert.ToInt64(arr_split[1]) : size;
}
/* Check the range and make sure it's treated according to the specs.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
*/
// End bytes can not be larger than $end.
anotherEnd = (anotherEnd > end) ? end : anotherEnd;
// Validate the requested range and return an error if it's not correct.
if (anotherStart > anotherEnd || anotherStart > size - 1 || anotherEnd >= size)
{
context.Response.ContentType = MimeMapping.GetMimeMapping(fullpath);
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
start = anotherStart;
end = anotherEnd;
length = end - start + 1; // Calculate new content length
fp = reader.BaseStream.Seek(start, SeekOrigin.Begin);
context.Response.StatusCode = 206;
}
}
// Notify the client the byte range we'll be outputting
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
context.Response.AddHeader("Content-Length", length.ToString());
// Start buffered download
context.Response.WriteFile(fullpath, fp, length);
context.Response.End();
}

Blackberry BrowserField : How to show images in Blackberry without rendering problems?

I'm trying to render images using BrowserField . But i'm having the problem that images shows like this (bad rendering):
The image is bigguer than screen , and i have used this code to load it:
public ImagesScreen(String urlImage,int number)
{
super(VERTICAL_SCROLL | HORIZONTAL_SCROLL);
BrowserFieldConfig config = new BrowserFieldConfig();
config.setProperty(BrowserFieldConfig.USER_SCALABLE, Boolean.TRUE);
browserField = new BrowserField(config);
scale = initscale = Float.valueOf(formatNumber(((float) 1 / (1703 / Display.getWidth())), 8, "."));
add(browserField);
Log.info("scala " + scale);//" + scale + "
String htmlContent = "<html><meta name='viewport' content='width = device-width,maximum-scale=10.0, minimum-scale=0.001, initial-scale=" + scale + ", user-scalable=yes' /><body style='margin: 0px;padding: 0px;float: left;'>";
for (int i = 1; i <= number;i++)
{
htmlContent += "<img width='1703' alt='' src='" + urlImage + "000"+i+".png"+"'/>";
}
System.out.println(urlImage);
htmlContent += "</body></html>";
browserField.displayContent(htmlContent, "http://localhost");
UiApplication.getUiApplication().pushScreen(this);
};
If i let the scale be 1 , it stills having that problem. Thanks for reading :) .
Let the BrowserField do all the work:
String imgFile = "..."; // here the image file pathname
String style = "..."; // here the css style
String imgTag = "<div class=\"image\"> <img src="
+ imgFile
+ "></img></div><div class=\"clear\"></div>";
String browserContent = "<html><style>" + style + "</style>" + imgTag + "</html>";
byte[] contentBytes;
try {
contentBytes = browserContent.getBytes("UTF-8");
browser.displayContent(contentBytes, "text/html; charset=UTF-8", "");
} catch (UnsupportedEncodingException e) {
...
}

AJAX getting truncated on paragraph

I'm having a strange problem when trying to updated a div with a couple of paragrahs of text from AJAX.
Here are functions I'm using:
var receivePapers = getXmlHttpRequestObject();
function get_papers(myCat){
if (receivePapers.readyState == 4 || receivePapers.readyState == 0) {
receivePapers.open("GET", 'http://server/path/tocode/file.php?get_papers=1&student_id=1&category=' + myCat, true);
receivePapers.onreadystatechange = handlereceivePapers;
receivePapers.send(null);
}
}
function handlereceivePapers() {
if (receivePapers.readyState == 4) {
var container_div = document.getElementById('paper_container');
var xmldoc = receivePapers.responseXML;
var paper_nodes = xmldoc.getElementsByTagName("paper");
var n_papers = paper_nodes.length;
// Clear the whole container div.
container_div.innerHTML = "";
container_div.innerHTML = "<table class='categoryHeader' width='100%'><tr><th class ='categoryHeader' width='80%' ><br/> " + paper_nodes[1].getElementsByTagName("category")[0].firstChild.nodeValue + "</br> <br/><br/></th></tr>";
container_div.innerHTML += "<tr><td>";
for (i = 0; i < n_papers; i++) {
var paper_id = paper_nodes[i].getElementsByTagName("paper_id");
var paper_title = paper_nodes[i].getElementsByTagName("paper_title");
var paper_desc = paper_nodes[i].getElementsByTagName("paper_desc");
var paper_time = paper_nodes[i].getElementsByTagName("paper_time");
var user_real_name = paper_nodes[i].getElementsByTagName("user_real_name");
var summary_div = document.createElement('div');
summary_div.innerHTML += "<table class='paper'><tr><td class='paperLike' width=80px rowspan=2 valign='top'><div id='" + paper_id[0].firstChild.nodeValue + "'> <img src='images/Like.png' style='padding-top:5px' border='0' /></div></td><td><table width='100%'><tr><td class='paperTitle' style='background-color:white; text-align=left; '><a class='paperTitle' style='padding-left:0;' href='#" + paper_id[0].firstChild.nodeValue + "'>" + paper_title[0].firstChild.nodeValue + "</a></td><td class='paperName' style='margin-right:0; width:200px; background-color:white; text-align:right; vertical-align:text-top;'><span align='right' style='background-color:white; text-align:right; vertical-align:text-top; ' > " + user_real_name[0].firstChild.nodeValue + "</span></td></tr></table></td><td rowspan='2' class='paperLength' style='width:80px; text-align:right; padding-top:8px;' >" + paper_time[0].firstChild.nodeValue + " minutes</td></tr><tr><td class='paperDescription' align='left' colspan='1'>" + paper_desc[0].firstChild.nodeValue + "</td></tr></table>";
container_div.appendChild(summary_div);
}
container_div.innerHTML += "</tr></td></table";
}
}
Here is the XML that's getting returned:
<root>
<paper id="23">
<paper_id>23</paper_id>
<paper_title>title</paper_title>
<paper_desc>
First paragraph of desc
<br/>
<br/>
Second paragraph of desc
<br/>
<br/>
Third paragraph of desc
<br/>
</paper_desc>
<paper_time>45</paper_time>
<user_real_name>Bob Student</user_real_name>
<user_id>2322</user_id>
<category>Languages</category>
</paper>
...
When I push the content to container_div only the first paragraph is showing up. If I stick a Javascript alert() in to return paper_desc it only contains the first paragraph. I've tried looking for other nodes but this says there's only 1 node:
alert(paper_nodes[i].getElementsByTagName("paper_desc").length);
You use paper_desc[0].firstChild.nodeValue
paper_desc[0] is a set of nodes: text nodes and br nodes. You get only the first child of this set, so you get only the first text.
Your alert() call only shows you have only one paper_desc node, not how many nodes you have inside.
I also found strange that you used paper_nodes[1] but I don't know if there is a second node in your XML and if you really want to target it.

prototype findElements querySelectorAll error

i'm call the "down" function but am getting an invalid argument using 1.6.1_rc2
here's the html snippet:
<TR id=000000214A class="activeRow searchResultsDisplayOver" conceptID="0000001KIU">
<TD>
<DIV class=gridRowWrapper>
<SPAN class=SynDesc>Asymmetric breasts</SPAN>
<DIV class=buttonWrapper>
<SPAN class=btnAddFav title="Add to Favorites"> </SPAN>
</DIV>
</DIV>
</TD>
</TR>
here's the code:
var description = row.down('span.SynDesc').innerHTML;
row is a dom reference to the element.
prototype is appending a # then the id of the element:
findElements: function(root) {
root = root || document;
var e = this.expression, results;
switch (this.mode) {
case 'selectorsAPI':
if (root !== document) {
var oldId = root.id, id = $(root).identify();
id = id.replace(/[\.:]/g, "\\$0");
e = "#" + id + " " + e;
}
results = $A(root.querySelectorAll(e)).map(Element.extend); <-- e = "#000000214A span.SynDesc"
root.id = oldId;
return results;
case 'xpath':
return document._getElementsByXPath(this.xpath, root);
default:
return this.matcher(root);
}
i get an "invalid argument" error?
if i put a breakpoint before the offending line and change e to be equal to "span.SynDesc" it works fine.
help. :)
I ran into this. Changing the TR's ID to start with a letter should fix the problem. It turns out that legal HTML IDs match /^[A-Za-z][A-Za-z0-9_:.-]*$/.

Resources