Theme Customizer: Properly handle redirects in the preview by setting wp_redirect_status to 200. props nacin, see #20507, #19910.

git-svn-id: http://core.svn.wordpress.org/trunk@20861 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
koopersmith 2012-05-24 01:48:32 +00:00
parent 0f259eaae1
commit 46f03144b0
2 changed files with 45 additions and 13 deletions

View File

@ -34,6 +34,9 @@ final class WP_Customize_Manager {
add_action( 'setup_theme', array( $this, 'setup_theme' ) );
add_action( 'wp_loaded', array( $this, 'wp_loaded' ) );
// Run wp_redirect_status late to make sure we override the status last.
add_action( 'wp_redirect_status', array( $this, 'wp_redirect_status' ), 1000 );
add_action( 'wp_ajax_customize_save', array( $this, 'save' ) );
add_action( 'customize_register', array( $this, 'register_controls' ) );
@ -210,6 +213,21 @@ final class WP_Customize_Manager {
$this->customize_preview_init();
}
/**
* Prevents AJAX requests from following redirects when previewing a theme
* by issuing a 200 response instead of a 30x.
*
* Instead, the JS will sniff out the location header.
*
* @since 3.4.0
*/
public function wp_redirect_status( $status ) {
if ( $this->is_preview() && ! is_admin() )
return 200;
return $status;
}
/**
* Decode the $_POST attribute used to override the WP_Customize_Setting values.
*

View File

@ -318,23 +318,29 @@
api.Messenger.prototype.initialize.call( this, params.url );
// We're dynamically generating the iframe, so the origin is set
// to the current window's location, not the url's.
this.origin.unlink( this.url ).set( window.location.href );
// Limit the URL to internal, front-end links.
this.url.setter( function( to ) {
// Bail if we're navigating to a different origin or wp-admin.
if ( 0 !== to.indexOf( self.origin() + '/' ) || -1 !== to.indexOf( 'wp-admin' ) )
return null;
return to;
});
// Refresh the preview when the URL is changed.
this.url.bind( this.refresh );
this.scroll = 0;
this.bind( 'scroll', function( distance ) {
this.scroll = distance;
});
// We're dynamically generating the iframe, so the origin is set
// to the current window's location, not the url's.
this.origin.unlink( this.url ).set( window.location.href );
this.bind( 'url', function( url ) {
// Bail if we're navigating to the current url, to a different origin, or wp-admin.
if ( this.url() == url || 0 !== url.indexOf( this.origin() + '/' ) || -1 !== url.indexOf( 'wp-admin' ) )
return;
this.url( url );
this.refresh();
});
// Update the URL when the iframe sends a URL message.
this.bind( 'url', this.url );
},
loader: function() {
if ( this.loading )
@ -365,7 +371,15 @@
type: 'POST',
data: this.query() || {},
success: function( response ) {
var iframe = self.loader()[0].contentWindow;
var iframe = self.loader()[0].contentWindow,
location = self.request.getResponseHeader('Location');
// Check if the location response header differs from the current URL.
// If so, the request was redirected; try loading the requested page.
if ( location && location != self.url() ) {
self.url( location );
return;
}
self.loader().one( 'load', self.loaded );