Index: wp-includes/admin-bar.php
===================================================================
--- wp-includes/admin-bar.php	(revision 21027)
+++ wp-includes/admin-bar.php	(working copy)
@@ -576,11 +576,12 @@
 	if ( ! current_user_can( 'edit_theme_options' ) )
 		return;
 
+	$current_url = is_ssl() ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
 	$wp_admin_bar->add_menu( array(
 		'parent' => 'appearance',
 		'id'     => 'customize',
 		'title'  => __('Customize'),
-		'href'   => wp_customize_url(),
+		'href'   => add_query_arg( 'url', urlencode( $current_url ), wp_customize_url() ),
 		'meta'   => array(
 			'class' => 'hide-if-no-customize',
 		),
Index: wp-includes/js/customize-base.dev.js
===================================================================
--- wp-includes/js/customize-base.dev.js	(revision 21027)
+++ wp-includes/js/customize-base.dev.js	(working copy)
@@ -498,7 +498,7 @@
 			$.extend( this, options || {} );
 
 			this.add( 'channel', params.channel );
-			this.add( 'url', params.url );
+			this.add( 'url', params.url || '' );
 			this.add( 'targetWindow', params.targetWindow || defaultTarget );
 			this.add( 'origin', this.url() ).link( this.url ).setter( function( to ) {
 				return to.replace( /([^:]+:\/\/[^\/]+).*/, '$1' );
Index: wp-admin/customize.php
===================================================================
--- wp-admin/customize.php	(revision 21027)
+++ wp-admin/customize.php	(working copy)
@@ -11,6 +11,10 @@
 if ( ! current_user_can( 'edit_theme_options' ) )
 	wp_die( __( 'Cheatin&#8217; uh?' ) );
 
+wp_reset_vars( array( 'url', 'return' ) );
+$url = urldecode( $url );
+$return = $return ? urldecode( $return ) : $url;
+
 global $wp_scripts, $wp_customize;
 
 $registered = $wp_scripts->registered;
@@ -64,7 +68,7 @@
 				submit_button( $save_text, 'primary', 'save', false );
 			?>
 			<img src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" />
-			<a class="back button" href="<?php echo esc_url( admin_url( 'themes.php' ) ); ?>">
+			<a class="back button" href="<?php echo esc_url( $return ? $return : admin_url( 'themes.php' ) ); ?>">
 				<?php _e( 'Cancel' ); ?>
 			</a>
 		</div>
@@ -146,13 +150,14 @@
 			'active'     => $wp_customize->is_theme_active(),
 		),
 		'url'      => array(
-			'preview'       => esc_url( home_url( '/' ) ),
+			'preview'       => esc_url( $url ? $url : home_url( '/' ) ),
 			'parent'        => esc_url( admin_url() ),
 			'activated'     => esc_url( admin_url( 'themes.php?activated=true' ) ),
 			'ajax'          => esc_url( admin_url( 'admin-ajax.php', 'relative' ) ),
 			'allowed'       => array_map( 'esc_url', $allowed_urls ),
 			'isCrossDomain' => $cross_domain,
 			'fallback'      => $fallback_url,
+			'home'          => esc_url( home_url( '/' ) ),
 		),
 		'browser'  => array(
 			'mobile' => wp_is_mobile(),
Index: wp-admin/js/customize-controls.dev.js
===================================================================
--- wp-admin/js/customize-controls.dev.js	(revision 21027)
+++ wp-admin/js/customize-controls.dev.js	(working copy)
@@ -403,7 +403,8 @@
 		 */
 		initialize: function( params, options ) {
 			var self = this,
-				rscheme = /^https?/;
+				rscheme = /^https?/,
+				url;
 
 			$.extend( this, options || {} );
 
@@ -444,6 +445,9 @@
 			this.container   = api.ensure( params.container );
 			this.allowedUrls = params.allowedUrls;
 
+			url = params.url;
+			delete params.url;
+
 			api.Messenger.prototype.initialize.call( this, params );
 
 			// We're dynamically generating the iframe, so the origin is set
@@ -488,7 +492,10 @@
 				return result ? result : null;
 			});
 
-			// Refresh the preview when the URL is changed.
+			// Set the url.
+			this.url( url );
+
+			// Refresh the preview when the URL is changed (but not yet).
 			this.url.bind( this.refresh );
 
 			this.scroll = 0;
@@ -635,8 +642,11 @@
 			} ) );
 		});
 
-		// Load the preview frame.
-		previewer.refresh();
+		// Check if preview url is valid and load the preview frame.
+		if ( previewer.url() )
+			previewer.refresh();
+		else
+			previewer.url( api.settings.url.home );
 
 		// Save and activated states
 		(function() {
