Twój najgorszy scenariusz nie jest taki zły, jak myślisz.
Już analizujesz kanał RSS, więc masz już adresy URL obrazów. Załóżmy, że masz adres URL obrazu, taki jak http://otherdomain.com/someimage.jpg
. Przepisujesz ten adres URL jako https://mydomain.com/imageserver?url=http://otherdomain.com/someimage.jpg&hash=abcdeafad
. W ten sposób przeglądarka zawsze wysyła żądania przez https, więc pozbywasz się problemów.
Następna część - utwórz stronę proxy lub serwlet, który wykonuje następujące czynności -
- Przeczytaj parametr url z ciągu zapytania i zweryfikuj skrót
- Pobierz obraz z serwera i proxy go z powrotem do przeglądarki
- Opcjonalnie buforuj obraz na dysku
To rozwiązanie ma kilka zalet. Nie musisz pobierać obrazu w momencie tworzenia HTML. Nie musisz przechowywać obrazów lokalnie. Ponadto jesteś bezpaństwowcem; adres URL zawiera wszystkie informacje niezbędne do wyświetlenia obrazu.
Wreszcie parametr hash służy do celów bezpieczeństwa; chcesz, aby serwlet obsługiwał obrazy tylko dla utworzonych adresów URL. Tak więc podczas tworzenia adresu URL oblicz go md5(image_url + secret_key)
i dołącz jako parametr hash. Zanim obsłużysz żądanie, ponownie oblicz skrót i porównaj go z tym, co zostało Ci przekazane. Ponieważ tajny_klucz jest znany tylko Tobie, nikt inny nie może tworzyć prawidłowych adresów URL.
Jeśli tworzysz w Javie, serwlet to tylko kilka linijek kodu. Powinieneś być w stanie przenieść poniższy kod do dowolnej innej technologii zaplecza.
/*
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);
}
}
Jeśli szukasz szybkiego rozwiązania do ładowania obrazów przez HTTPS, może Cię zainteresować bezpłatna usługa odwrotnego proxy pod adresem https://images.weserv.nl/ . To było dokładnie to, czego szukałem.
Jeśli szukasz płatnego rozwiązania, korzystałem wcześniej z Cloudinary.com, który również działa dobrze, ale moim zdaniem jest zbyt drogi tylko do tego zadania.
źródło
Nie wiem, czy pasowałoby to do tego, co robisz, ale w ramach szybkiego rozwiązania „opakowałbym” zawartość http w skrypt https. Na przykład na twojej stronie, która jest obsługiwana przez https, wprowadziłbym iframe, który zastąpiłby twój kanał rss, a w atr src elementu iframe umieściłbym na serwerze adres URL skryptu, który przechwytuje kanał i wyprowadza HTML. skrypt czyta kanał przez http i wyprowadza go przez https (czyli „zawija”)
Tylko myśl
źródło
Jeśli chodzi o twoje drugie wymaganie - możesz być w stanie wykorzystać zdarzenie onerror, tj.
<img onerror="some javascript;"...
Aktualizacja:
Możesz także spróbować wykonać iterację
document.images
w dom. Istniejecomplete
właściwość logiczna, której możesz użyć. Nie wiem na pewno, czy to będzie odpowiednie, ale warto zbadać.źródło
Najlepiej byłoby po prostu mieć zawartość http na https
źródło
Czasami, podobnie jak w aplikacjach na Facebooku, nie możemy mieć niezabezpieczonych treści na bezpiecznej stronie. nie możemy też tworzyć lokalnych treści. na przykład aplikacja, która będzie ładowana w iFrame, nie jest prostą treścią i nie możemy uczynić jej lokalną.
Myślę, że nigdy nie powinniśmy ładować zawartości http w https, a także nie powinniśmy zmieniać strony https na wersję http, aby zapobiec wyświetlaniu okna błędu.
jedynym sposobem, który zapewni bezpieczeństwo użytkownika, jest korzystanie z wszystkich treści w wersji https, http://developers.facebook.com/blog/post/499/
źródło
Zaakceptowana odpowiedź pomogła mi zaktualizować to zarówno do PHP, jak i CORS, więc pomyślałem, że dołączę rozwiązanie dla innych:
czysty PHP / HTML:
javascript / jQuery:
imageserve.php Zobacz http://stackoverflow.com/questions/8719276/cors-with-php-headers?noredirect=1&lq=1, aby uzyskać więcej informacji na temat CORS
źródło
Po prostu: NIE Rób tego. Treść HTTP na stronie HTTPS jest z natury niepewna. Punkt. Dlatego IE wyświetla ostrzeżenie. Pozbycie się ostrzeżenia to głupie podejście.
Zamiast tego strona HTTPS powinna zawierać tylko zawartość HTTPS. Upewnij się, że treść może być ładowana również przez HTTPS i odwołaj się do niej przez https, jeśli strona jest ładowana przez https. W przypadku treści zewnętrznych będzie to oznaczać ładowanie i buforowanie elementów lokalnie, tak aby były dostępne przez https - jasne. Niestety nie da się tego obejść.
Ostrzeżenie jest tam z dobrego powodu. Poważnie. Poświęć 5 minut na zastanowienie się, jak przejąć wyświetlaną stronę https z niestandardową zawartością - będziesz zaskoczony.
źródło
Zdaję sobie sprawę, że jest to stary wątek, ale jedną z opcji jest po prostu usunięcie http: części z adresu URL obrazu, aby „ http: //some/image.jpg ” stało się „//some/image.jpg”. Będzie to również działać z sieciami CDN
źródło
Najlepszy sposób na pracę dla mnie
źródło