Есть ли способ удалить %20 из динамически создаваемых хлебных крошек?

Итак, я возился с этой записью Динамические хлебные крошки и наткнулся на Проблема, из-за которой, если в имени каталога есть пробел, то %20 добавляется к фактической видимой навигационной цепочке. Будет ли это удалено с помощью функции decodeURI() или есть лучший способ?

Вот js:

 var crumbsep = " • ";
 var precrumb = "<span class=\"crumb\">";
 var postcrumb = "</span>";
 var sectionsep = "/";
 var rootpath = "/"; // Use "/" for root of domain.
 var rootname = "Home";

 var ucfirst = 1; // if set to 1, makes "directory" default to "Directory"

 var objurl = new Object;

 // Grab the page's url and break it up into directory pieces
 var pageurl = (new String(document.location));
 var protocol = pageurl.substring(0, pageurl.indexOf("//") + 2);
 pageurl = pageurl.replace(protocol, ""); // remove protocol from pageurl
 var rooturl = pageurl.substring(0, pageurl.indexOf(rootpath) + rootpath.length); // find rooturl
 if (rooturl.charAt(rooturl.length - 1) == "/") //remove trailing slash
 { 
 rooturl = rooturl.substring(0, rooturl.length - 1); 
 }
 pageurl = pageurl.replace(rooturl, ""); // remove rooturl from pageurl
 if (pageurl.charAt(0) == '/') // remove beginning slash
 { 
 pageurl = pageurl.substring(1, pageurl.length); 
 }

 var page_ar = pageurl.split(sectionsep);
 var currenturl = protocol + rooturl;
 var allbread = precrumb + "<a href=\"" + currenturl + "\">" + rootname + "</a>" + postcrumb; // start with root

 for (i=0; i < page_ar.length-1; i++)
 { 
 var displayname = "";
   currenturl += "/" + page_ar[i];
   if (objurl[page_ar[i]])
   { 
   displayname = objurl[page_ar[i]]; 
   }
   else
   { 
   if (ucfirst == 1)
  { 
  displayname = page_ar[i].charAt(0).toUpperCase() + page_ar[i].substring(1); 
  }
  else
  { 
  displayname = page_ar[i];
  }
   }
   if ( i < page_ar.length -2 )
  { 
  allbread += precrumb + crumbsep +  "<a href=\"" + currenturl + "\">" + displayname + "</a>" + postcrumb; 
  }
   else
    { 
    allbread += crumbsep +  displayname; 
    }
 }
 document.write(allbread);

Если использовать decodeURI(), куда именно он пойдет? Кроме того, более несвязанный вопрос: можно ли добавить к приведенному выше коду опцию, которая сделает фактическую страницу внутри каталога включенной в хлебные крошки в качестве последнего элемента, а не последнего каталога? Не очень важно, но подумал, что тоже спрошу. Спасибо за любой вклад!


person CU3ED    schedule 17.11.2010    source источник


Ответы (2)


Да, decodeURI поможет. Вы можете добавить строку displayname = decodeURI(displayname); прямо перед if, которая читается как if ( i < page_ar.length -2 ):

...
displayname = decodeURI(displayname);
if ( i < page_ar.length -2 )
...

Обратите внимание, что, поскольку displayname и currenturl в конечном итоге встраиваются непосредственно в необработанную строку HTML, любые специальные символы HTML должны быть экранированы в первую очередь, иначе вы будете открыты для некоторых XSS-атаки (представьте, что какой-то злоумышленник публикует ссылку на ваш сайт, например yoursite.com/valid/page/%3Cscript%3Ealert%28%22Oh%20no%2C% 20not%20XSS%21%22%29%3C%2Fscript%3E). Один из самых простых способов сделать это описан в этом ответе, хотя для этого требуется jQuery.

Если вы хотите, чтобы текущая страница была включена в «хлебные крошки», я считаю, что достаточно изменить цикл, чтобы перейти от 0 к page_ar.length вместо page_ar.length - 1:

...
for (i=0; i < page_ar.length; i++)
...
person Cameron    schedule 17.11.2010
comment
Спасибо за ваш вклад, Кэм, и за дополнительную информацию об экранировании html-символов. Хорошая вещь! - person CU3ED; 20.11.2010

Вы должны использовать decodeURIComponent(), а не decodeURI() для этого. Немного сложно понять, что вы пытаетесь сделать, но вот более простой код, который даст вам массив «каталогов» в текущем URI, декодированный:

var dirs = location.pathname.split('/');
for (var i=0,len=dirs.length;i<len;++i){
  dirs[i] = decodeURIComponent(dirs[i]);
}
person Phrogz    schedule 17.11.2010