From 320916cc535adcb1ef16e187fea30f09a4ddc69e Mon Sep 17 00:00:00 2001 From: Daryl Koopersmith Date: Tue, 8 May 2012 20:13:34 +0000 Subject: [PATCH] Theme Customizer: Add cross-domain handling for when the admin and front-end are different origins. Handles both ajax and postMessage calls. props rboren, mdawaffe, nacin. see #20507, #19910. git-svn-id: https://develop.svn.wordpress.org/trunk@20741 602fd350-edb4-49c9-b593-d223f7449a82 --- wp-includes/class-wp-customize.php | 14 +++++++++++-- wp-includes/js/customize-controls.dev.js | 25 +++++++++++++++++------- wp-includes/js/customize-preview.dev.js | 2 +- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/wp-includes/class-wp-customize.php b/wp-includes/class-wp-customize.php index b0758111ba..198d979bfa 100644 --- a/wp-includes/class-wp-customize.php +++ b/wp-includes/class-wp-customize.php @@ -71,6 +71,18 @@ final class WP_Customize { if ( ! isset( $_REQUEST['customize'] ) || 'on' != $_REQUEST['customize'] ) return; + $url = parse_url( admin_url() ); + $allowed_origins = array( 'http://' . $url[ 'host' ], 'https://' . $url[ 'host' ] ); + // @todo preserve port? + if ( isset( $_SERVER[ 'HTTP_ORIGIN' ] ) && in_array( $_SERVER[ 'HTTP_ORIGIN' ], $allowed_origins ) ) { + $origin = $_SERVER[ 'HTTP_ORIGIN' ]; + } else { + $origin = $url[ 'scheme' ] . '://' . $url[ 'host' ]; + } + + @header( 'Access-Control-Allow-Origin: ' . $origin ); + @header( 'Access-Control-Allow-Credentials: true' ); + $this->start_previewing_theme(); show_admin_bar( false ); } @@ -198,8 +210,6 @@ final class WP_Customize { */ public function customize_preview_settings() { $settings = array( - // @todo: Perhaps grab the URL via $_POST? - 'parent' => esc_url( admin_url( 'themes.php' ) ), 'values' => array(), ); diff --git a/wp-includes/js/customize-controls.dev.js b/wp-includes/js/customize-controls.dev.js index e771756023..15b532b92b 100644 --- a/wp-includes/js/customize-controls.dev.js +++ b/wp-includes/js/customize-controls.dev.js @@ -311,6 +311,10 @@ 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 ); + 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' ) ) @@ -343,15 +347,22 @@ if ( this.request ) this.request.abort(); - this.request = $.post( this.url(), this.query() || {}, function( response ) { - var iframe = self.loader()[0].contentWindow; + this.request = $.ajax( this.url(), { + type: 'POST', + data: this.query() || {}, + success: function( response ) { + var iframe = self.loader()[0].contentWindow; - self.loader().one( 'load', self.loaded ); + self.loader().one( 'load', self.loaded ); - iframe.document.open(); - iframe.document.write( response ); - iframe.document.close(); - }); + iframe.document.open(); + iframe.document.write( response ); + iframe.document.close(); + }, + xhrFields: { + withCredentials: true + } + } ); } }); diff --git a/wp-includes/js/customize-preview.dev.js b/wp-includes/js/customize-preview.dev.js index 393e593b8e..6aefdd1c89 100644 --- a/wp-includes/js/customize-preview.dev.js +++ b/wp-includes/js/customize-preview.dev.js @@ -37,7 +37,7 @@ var preview, body; - preview = new api.Preview( api.settings.parent ); + preview = new api.Preview( window.location.href ); $.each( api.settings.values, function( id, value ) { api.set( id, value );