HTTPSを介して完全にアクセスされるサイトがありますが、時々外部コンテンツ HTTP(主にRSSフィードからの画像)を表示します。私たちのユーザーの大部分もIE6にこだわっています。
理想的には次の両方を行いたい
私は、最初の目的は単に可能ではないと思うが、2番目の目的で十分かもしれない。
最悪の場合のシナリオは、RSSフィードをインポートするときに解析し、画像をローカルに保存してユーザーがその方法でアクセスできるようにすることですが、それでもほとんど利益が得られないのは大変な苦痛のようです。
あなたの最悪のシナリオはあなたが思うほど悪くはありません。
すでにRSSフィードを解析しているので、画像のURLはすでにあります。 http://otherdomain.com/someimage.jpg
のような画像URLがあるとします。このURLをhttps://mydomain.com/imageserver?url=http://otherdomain.com/someimage.jpg&hash=abcdeafad
に書き換えます。このようにして、ブラウザは常にhttps経由でリクエストを行うため、問題を取り除くことができます。
次の部分-次のことを行うプロキシページまたはサーブレットを作成します-
このソリューションにはいくつかの利点があります。 htmlの作成時にイメージをダウンロードする必要はありません。画像をローカルに保存する必要はありません。また、あなたは無国籍です。 URLには、画像を提供するために必要なすべての情報が含まれています。
最後に、ハッシュパラメータはセキュリティ用です。構築したURLの画像のみをサーブレットで処理する必要があります。したがって、URLを作成するときは、md5(image_url + secret_key)
を計算し、それをハッシュパラメーターとして追加します。リクエストを処理する前に、ハッシュを再計算し、渡されたものと比較します。 secret_keyはユーザーのみが知っているため、他の誰も有効なURLを作成できません。
Javaで開発している場合、サーブレットはほんの数行のコードです。以下のコードを他のバックエンドテクノロジーに移植できるはずです。
/*
targetURL is the url you get from RSS feeds
request and response are wrt to the browser
Assumes you have commons-io in your classpath
*/
protected void proxyResponse (String targetURL, HttpServletRequest request,
HttpServletResponse response) throws IOException {
GetMethod get = new GetMethod(targetURL);
get.setFollowRedirects(true);
/*
* Proxy the request headers from the browser to the target server
*/
Enumeration headers = request.getHeaderNames();
while(headers!=null && headers.hasMoreElements())
{
String headerName = (String)headers.nextElement();
String headerValue = request.getHeader(headerName);
if(headerValue != null)
{
get.addRequestHeader(headerName, headerValue);
}
}
/*Make a request to the target server*/
m_httpClient.executeMethod(get);
/*
* Set the status code
*/
response.setStatus(get.getStatusCode());
/*
* proxy the response headers to the browser
*/
Header responseHeaders[] = get.getResponseHeaders();
for(int i=0; i<responseHeaders.length; i++)
{
String headerName = responseHeaders[i].getName();
String headerValue = responseHeaders[i].getValue();
if(headerValue != null)
{
response.addHeader(headerName, headerValue);
}
}
/*
* Proxy the response body to the browser
*/
InputStream in = get.getResponseBodyAsStream();
OutputStream out = response.getOutputStream();
/*
* If the server sends a 204 not-modified response, the InputStream will be null.
*/
if (in !=null) {
IOUtils.copy(in, out);
}
}
HTTPS経由で画像をロードする簡単なソリューションを探している場合は、 https://images.weserv.nl/ にある無料のリバースプロキシサービスに興味があるかもしれません。それはまさに私が探していたものでした。
有料のソリューションをお探しの場合、以前はCloudinary.comを使用しましたが、これもうまく機能しますが、このタスクだけでは高すぎると思います。
これがあなたのやっていることに合うかどうかはわかりませんが、簡単な修正として、httpコンテンツをhttpsスクリプトに「ラップ」します。たとえば、httpsを介して提供されるページでは、rssフィードを置き換えるiframeを導入し、iframeのsrc attrに、フィードをキャプチャしてhtmlを出力するスクリプトのURLをサーバーに配置します。スクリプトはhttpを介してフィードを読み取り、httpsを介して出力します(つまり、「ラッピング」)
ちょっとした考え
2番目の要件について-onerrorイベントを利用できる場合があります。 <img onerror="some javascript;"...
更新:
Domでdocument.images
を反復処理することもできます。使用できる可能性のあるcomplete
ブールプロパティがあります。これが適切かどうかはわかりませんが、調査する価値があるかもしれません。
Httpsにhttpコンテンツを置くだけが最善でしょう
受け入れられた回答は、これをPHPとCORSの両方に更新するのに役立ちました。したがって、私は他の人のためのソリューションを含めると思いました。
純粋なPHP/HTML:
<?php // (the originating page, where you want to show the image)
// set your image location in whatever manner you need
$imageLocation = "http://example.com/exampleImage.png";
// set the location of your 'imageserve' program
$imageserveLocation = "https://example.com/imageserve.php";
// we'll look at the imageLocation and if it is already https, don't do anything, but if it is http, then run it through imageserve.php
$imageURL = (strstr("https://",$imageLocation)?"": $imageserveLocation . "?image=") . $imageLocation;
?>
<!-- this is the HTML image -->
<img src="<?php echo $imageURL ?>" />
javascript/jQuery:
<img id="theImage" src="" />
<script>
var imageLocation = "http://example.com/exampleImage.png";
var imageserveLocation = "https://example.com/imageserve.php";
var imageURL = ((imageLocation.indexOf("https://") !== -1) ? "" : imageserveLocation + "?image=") + imageLocation;
// I'm using jQuery, but you can use just javascript...
$("#theImage").prop('src',imageURL);
</script>
imageserve.php http://stackoverflow.com/questions/8719276/cors-with-php-headers?noredirect=1&lq=1 CORSの詳細を参照
<?php
// set your secure site URL here (where you are showing the images)
$mySecureSite = "https://example.com";
// here, you can set what kinds of images you will accept
$supported_images = array('png','jpeg','jpg','gif','ico');
// this is an ultra-minimal CORS - sending trusted data to yourself
header("Access-Control-Allow-Origin: $mySecureSite");
$parts = pathinfo($_GET['image']);
$extension = $parts['extension'];
if(in_array($extension,$supported_images)) {
header("Content-Type: image/$extension");
$image = file_get_contents($_GET['image']);
echo $image;
}
Facebookアプリのように、安全なページに安全でないコンテンツを含めることはできません。また、それらのコンテンツをローカルにすることはできません。たとえば、iFrameに読み込まれるアプリは単純なコンテンツではなく、ローカルにすることはできません。
Httpsコンテンツをhttpsにロードすることは絶対にしないでください。また、エラーダイアログを防ぐためにhttpsバージョンをhttpバージョンにフォールバックしないでください。
ユーザーのセキュリティを確保する唯一の方法は、すべてのコンテンツのhttpsバージョンを使用することです http://developers.facebook.com/blog/post/499/