2017-07-21 12:48
浏览 180

jQuery AJAX - 加载方法失败时重定向到404页面

My website loads all the pages through AJAX, with the jQuery load method. I did my best to adapt this tutorial to Wordpress.

My problem today, is that when the load method returns an error (such as 404 because of a broken link), the AJAX transition doesn't finish, and the page doesn't change at all.

- How can I execute something when the load method fails ?

EDIT : I found a solution for that in the docs.

section.load(url + ' .cd-main-content > *', function (response, status, xhr) {
    //the code

Now it doesn't help me as I thought it would. Because, response returns the 404 page content as expected, status returns error and xhr [object OBJECT]. What I don't get is why the response html isn't being loaded in the div...

- How can I know this is a 404 error ?

Successfully checked for a 404 error using :

if (status == "error" && xhr.status == "404") {
    console.log('this is a 404 error');

I tried executing my code in the load function conditionnaly if the xhr.status is 404 or if the status is success, with no luck. Still not working. Can anybody helppp?

- How can I redirect to wordpress's 404.php page with jQuery ?

- How should I treat other error codes ?

Lots of questions sorry... I don't know where to start

Here's the Javascript :

jQuery(document).ready(function (event) {

    // select website's root url
    var rootUrl = aws_data.rootUrl; 
    var isAnimating = false, 
        newLocation = '', 
        firstLoad = false;

    // Internal Helper
    $.expr[':'].internal = function(obj, index, meta, stack){
        // Prepare
            $this = $(obj),
            urlinternal = $this.attr('href')||'',

        // Check link
        isInternalLink = urlinternal.substring(0,rootUrl.length) === rootUrl || urlinternal.indexOf(':') === -1;

        // Ignore or Keep
        return isInternalLink;

    //trigger smooth transition from the actual page to the new one, excluding event on non relevant links  
    $('main').on('click', 'a[href]:internal:not(.no-ajaxy,.love-button,[href^="#"],[href*="#respond"],[href*="wp-login"],[href*="wp-admin"])', function (event) { 
        //detect which page has been selected
        var newPage = $(this).attr('href');
        //if the page is not already being animated - trigger animation
        if (!isAnimating) changePage(newPage, true);
        firstLoad = true;
    //detect the 'popstate' event - e.g. user clicking the back button
    $(window).on('popstate', function (e) {
        if (firstLoad) {
            Safari emits a popstate event on page load - check if firstLoad is true before animating
            if it's false - the page has just been loaded 
            var newPageArray = location.pathname.split('/'), //this is the url of the page to be loaded 
                //newPage = newPageArray[newPageArray.length - 1];
                newPage = window.location.href;
            if (!isAnimating && newLocation != newPage) changePage(newPage, false);
        firstLoad = true;

    function changePage(url, bool) {
        isAnimating = true;
        // trigger page animation
        $('.cd-loading-bar').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function () {
            loadNewContent(url, bool);
            newLocation = url;
            $('.cd-loading-bar').off('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend');
        //if browser doesn't support CSS transitions
        if (!transitionsSupported()) {
            loadNewContent(url, bool);
            newLocation = url;

    function loadNewContent(url, bool) {
        // I don't understand the line below
        url = ('' === url) ? rootUrl : url; 
        var newSection = 'cd-' + url.replace(rootUrl, ""); 
        var section = $('<div class="cd-main-content ' + newSection + '"></div>');
        // this ajax request helps me applied Wordpress classes on the body element, which is not being reloaded below
        $.ajax({url: url, 
            success: function(data){
                data = data.replace("<body", "<container").replace("body>", "container>");
                var classes = $(data).filter("container").attr("class"); 
                $("body").attr("class", classes + " page-is-changing"); 

        section.load(url + ' .cd-main-content > *', function (event) {
            // load new content and replace <main> content with the new one
            var delay = 1200; 

            //functions to execute after DOM is loaded
            window.scrollTo(0, 0);
            //ga('send', 'pageview', window.location.pathname);

            setTimeout(function () {
                //wait for the end of the transition on the loading bar before revealing the new content
                $('.cd-loading-bar').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function () {
                    isAnimating = false;
                    $('.cd-loading-bar').off('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend');
                if (!transitionsSupported()) isAnimating = false;
            }, delay);
            if (url != window.location && bool) {
                //add the new page to the window.history
                //if the new page was triggered by a 'popstate' event, don't add it
                    path: url
                }, '', url);


    function transitionsSupported() {
        return $('html').hasClass('csstransitions');
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongzaheng4449 2017-07-21 14:29

    I finally solved my problem.

    After realizing that the response returned what I wanted, I took a guess and assumed that the problem was that the status returned was 404 when in fact, 200 was what I wanted.

    So I added status_header(200); at the beginning of my 404.php file and now it works perfectly.

    I hope it's not problematic to ditch the 404 status code but that's my only solution for now.

    解决 无用
    打赏 举报

相关推荐 更多相似问题