diff --git a/src/wp-admin/css/press-this.css b/src/wp-admin/css/press-this.css
index 42a76c7d49..00bdad1762 100644
--- a/src/wp-admin/css/press-this.css
+++ b/src/wp-admin/css/press-this.css
@@ -1363,6 +1363,33 @@ html {
 	margin: 0 auto;
 }
 
+.spinner {
+	height: 20px;
+	width: 20px;
+	display: inline-block;
+	visibility: hidden;
+	background: url(../images/spinner.gif) no-repeat center;
+	-webkit-background-size: 20px 20px;
+	background-size: 20px 20px;
+	opacity: 0.7;
+	filter: alpha(opacity=70);
+	line-height: 30px;
+	vertical-align: baseline;
+}
+
+@media print,
+	(-webkit-min-device-pixel-ratio: 1.25),
+	(min-resolution: 120dpi) {
+
+	.spinner {
+		background-image: url(../images/spinner-2x.gif);
+	}
+}
+
+.spinner.is-visible {
+	visibility: visible;
+}
+
 /* Make the text inside the editor textarea white. Prevents a "flash" on loading the page */
 #pressthis {
 	color: #fff;
diff --git a/src/wp-admin/includes/class-wp-press-this.php b/src/wp-admin/includes/class-wp-press-this.php
index d5edd17a15..11a9371fa6 100644
--- a/src/wp-admin/includes/class-wp-press-this.php
+++ b/src/wp-admin/includes/class-wp-press-this.php
@@ -148,23 +148,28 @@ class WP_Press_This {
 			}
 
 			if ( 'publish' === get_post_status( $post_id ) ) {
-				/**
-				 * Filter the URL to redirect to when Press This saves.
-				 *
-				 * @since 4.2.0
-				 *
-				 * @param string $url     Redirect URL. If `$status` is 'publish', this will be the post permalink.
-				 *                        Otherwise, the post edit URL will be used.
-				 * @param int    $post_id Post ID.
-				 * @param string $status  Post status.
-				 */
-				$redirect = apply_filters( 'press_this_save_redirect', get_post_permalink( $post_id ), $post_id, $post['post_status'] );
+				$redirect = get_post_permalink( $post_id );
 			} else {
-				/** This filter is documented in wp-admin/includes/class-wp-press-this.php */
-				$redirect = apply_filters( 'press_this_save_redirect', get_edit_post_link( $post_id, 'raw' ), $post_id, $post['post_status'] );
+				$redirect = false;
 			}
 
-			wp_send_json_success( array( 'redirect' => $redirect ) );
+			/**
+			 * Filter the URL to redirect to when Press This saves.
+			 *
+			 * @since 4.2.0
+			 *
+			 * @param string $url     Redirect URL. If `$status` is 'publish', this will be the post permalink.
+			 *                        Otherwise, the post edit URL will be used.
+			 * @param int    $post_id Post ID.
+			 * @param string $status  Post status.
+			 */
+			$redirect = apply_filters( 'press_this_save_redirect', $redirect, $post_id, $post['post_status'] );
+
+			if ( $redirect ) {
+				wp_send_json_success( array( 'redirect' => $redirect ) );
+			} else {
+				wp_send_json_success( array( 'postSaved' => true ) );
+			}
 		}
 	}
 
@@ -1339,6 +1344,7 @@ class WP_Press_This {
 			</button>
 		</div>
 		<div class="post-actions">
+			<span class="spinner">&nbsp;</span>
 			<button type="button" class="button-subtle draft-button"><?php _e( 'Save Draft' ); ?></button>
 			<button type="button" class="button-subtle preview-button"><?php _e( 'Preview' ); ?></button>
 			<button type="button" class="button-primary publish-button"><?php echo ( current_user_can( 'publish_posts' ) ) ? __( 'Publish' ) : __( 'Submit for Review' ); ?></button>
diff --git a/src/wp-admin/js/press-this.js b/src/wp-admin/js/press-this.js
index 2f1a60254b..eba5c0e298 100644
--- a/src/wp-admin/js/press-this.js
+++ b/src/wp-admin/js/press-this.js
@@ -101,7 +101,7 @@
 		 * Show UX spinner
 		 */
 		function showSpinner() {
-			$( '#spinner' ).addClass( 'show' );
+			$( '.spinner' ).addClass( 'is-visible' );
 			$( '.post-actions button' ).each( function() {
 				$( this ).attr( 'disabled', 'disabled' );
 			} );
@@ -111,7 +111,7 @@
 		 * Hide UX spinner
 		 */
 		function hideSpinner() {
-			$( '#spinner' ).removeClass( 'show' );
+			$( '.spinner' ).removeClass( 'is-visible' );
 			$( '.post-actions button' ).each( function() {
 				$( this ).removeAttr( 'disabled' );
 			} );
@@ -181,24 +181,28 @@
 			$.ajax( {
 				type: 'post',
 				url: window.ajaxurl,
-				data: data,
-				success: function( response ) {
-					if ( ! response.success ) {
-						renderError( response.data.errorMessage );
-						hideSpinner();
-					} else if ( response.data.redirect ) {
-						if ( window.opener && settings.redirInParent ) {
-							try {
-								window.opener.location.href = response.data.redirect;
-							} catch( er ) {}
+				data: data
+			}).always( function() {
+				hideSpinner();
+			}).done( function( response ) {
+				if ( ! response.success ) {
+					renderError( response.data.errorMessage );
+				} else if ( response.data.redirect ) {
+					if ( window.opener && settings.redirInParent ) {
+						try {
+							window.opener.location.href = response.data.redirect;
+						} catch( er ) {}
 
-							window.self.close();
-						} else {
-							window.location.href = response.data.redirect;
-						}
+						window.self.close();
+					} else {
+						window.location.href = response.data.redirect;
 					}
+				} else if ( response.data.postSaved ) {
+					// show "success" message?
 				}
-			} );
+			}).fail( function() {
+				renderError( __( 'serverError' ) );
+			});
 		}
 
 		/**
diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php
index ea7f5f4ef7..ecab928398 100644
--- a/src/wp-includes/script-loader.php
+++ b/src/wp-includes/script-loader.php
@@ -478,7 +478,7 @@ function wp_default_scripts( &$scripts ) {
 		$scripts->add( 'press-this', "/wp-admin/js/press-this$suffix.js", array( 'jquery', 'tags-box' ), false, 1 );
 		did_action( 'init' ) && $scripts->localize( 'press-this', 'pressThisL10n', array(
 			'newPost' => __( 'Title' ),
-			'unexpectedError' => __( 'Sorry, but an unexpected error occurred.' ),
+			'serverError' => __( 'Connection lost or the server is busy. Please try again later.' ),
 			'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.' ),
 			/* translators: %d: nth embed found in a post */
 			'suggestedEmbedAlt' => __( 'Suggested embed #%d' ),