Refused to display/connect when previewing entry on multi-site setup I run a multi-site setup with four sites; one on unicorn.com and one on all-your-base.com. 

The way Craft CMS licensing works, you can run multiple sites on different domains on the same license/install, but you have to edit all the sites from just one domain - unicorn.com in this case. 

When I click "live preview", from unicorn.com all I see is a sad pixelated face and a message saying "all-your-base.com refused to connect."



Console says: "Refused to display 'https://all-your-base.com/...' in a frame because it set X-Frame-Options to 'sameorigin'
X-Frame-Options

The problem is that your site's .htaccess file prevents unicorn.com from viewing all-your-base.com in an iframe because the X-Frame-Options header has not been configured for allowing this. 

Securing Craft mentions that you have to add headers for: 


Strict-Transport-Security 
X-Frame-Options X-XSS-Protection
X-Content-Type-Options
Content-Security-Policy
Public-Key-Pins


So although the following .htaccess-code doesn't add all of these headers, they together make the "refused to connect" go away, by allowing the frame-ancestor to be unicorn.com even when previewing content on all-your-base.com in an iframe (which is how the preview works).

# Unset X-Frame-Options that has been previously set possibly by Craft 
Header unset X-Frame-Options

# Allow unicorn.com to request itself in iframes (for live preview)
Header always set X-Frame-Options "ALLOW-FROM https://unicorn.com/"

# Allow unicorn.com to request all-your-base.com in iframes (for live preview)
Header set Content-Security-Policy "frame-ancestors unicorn.com"


These headers are simply strings that are attached to - you guessed it - the header of the HTML-page that is transmitted from the server. 

It's up to the  browser how to interpret them. Content-Security-Policy is for instance not supported on IE11. 

In this case, Content-Security-Policy is used by Chrome and X-Frame-Options is used by IE11 and others. 

Access-Control-Allow-Origin

You might also get error messages in the console because Access-Control-Allow-Origin is missing. Here is an example of setting that header. Note that it doesn't support multiple domains, so here I serve the local development address together with the production site address using the SetEnvIf command: 

SetEnvIf Origin "http(s)?://?(unicorn.com|unicorn.local)$" AccessControlAllowOrigin=$0
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header merge Vary Origin
Header set Access-Control-Allow-Credentials "true"