एचटीटीपीएस पृष्ठों में HTTP सामग्री के साथ काम करना


89

हमारे पास एक ऐसी साइट है जो पूरी तरह से HTTPS तक पहुंचती है, लेकिन कभी-कभी बाहरी सामग्री प्रदर्शित करती है जो HTTP (आरएसएस फ़ीड से चित्र, मुख्य रूप से) है। हमारे उपयोगकर्ताओं के विशाल बहुमत भी IE6 पर अटके हुए हैं।

मैं आदर्श रूप से निम्नलिखित दोनों को करना चाहूंगा

  • असुरक्षित सामग्री के बारे में IE चेतावनी संदेश को रोकें (ताकि मैं कम घुसपैठ दिखा सकूं, जैसे नीचे दिए गए डिफ़ॉल्ट आइकन के साथ छवियों को बदलकर)
  • उन छवियों के स्थान पर उपयोगकर्ताओं के लिए कुछ उपयोगी प्रस्तुत करें जिन्हें वे अन्यथा नहीं देख सकते हैं; अगर कुछ जेएस था तो मैं यह पता लगाने के लिए दौड़ सकता हूं कि कौन सी छवियां लोड नहीं हुई हैं और उन्हें हमारी जगह एक छवि के साथ बदल दें, जो बहुत अच्छा होगा।

मुझे संदेह है कि पहला उद्देश्य केवल संभव नहीं है, लेकिन दूसरा पर्याप्त हो सकता है।

सबसे खराब स्थिति यह है कि मैं आरएसएस फ़ीड को पार्स करता हूं जब हम उन्हें आयात करते हैं, छवियों को स्थानीय स्तर पर संग्रहीत करते हैं ताकि उपयोगकर्ता उन्हें इस तरह से एक्सेस कर सकें, लेकिन यह काफी कम लाभ के लिए बहुत दर्द की तरह लगता है।

जवाबों:


147

आपका सबसे खराब मामला उतना बुरा नहीं है जितना आप सोचते हैं।

आप पहले से ही आरएसएस फ़ीड को पार्स कर रहे हैं, इसलिए आपके पास पहले से ही छवि URL हैं। मान लें कि आपके पास एक छवि URL जैसा है http://otherdomain.com/someimage.jpg। आप इस URL को फिर से लिखें https://mydomain.com/imageserver?url=http://otherdomain.com/someimage.jpg&hash=abcdeafad। इस तरह, ब्राउज़र हमेशा https पर अनुरोध करता है, जिससे आपको समस्याओं से छुटकारा मिलता है।

अगला भाग - एक प्रॉक्सी पृष्ठ या सर्वलेट बनाएं जो निम्नलिखित कार्य करता है -

  1. क्वेरी स्ट्रिंग से url पैरामीटर पढ़ें, और हैश सत्यापित करें
  2. सर्वर से छवि डाउनलोड करें, और इसे वापस ब्राउज़र पर प्रॉक्सी करें
  3. वैकल्पिक रूप से, डिस्क पर छवि को कैश करें

इस उपाय के कुछ फायदे हैं। Html बनाने के समय आपको इमेज डाउनलोड नहीं करनी है। आपको छवियों को स्थानीय रूप से संग्रहीत करने की आवश्यकता नहीं है। इसके अलावा, आप स्टेटलेस हैं; url में छवि की सेवा के लिए आवश्यक सभी जानकारी शामिल है।

अंत में, हैश पैरामीटर सुरक्षा के लिए है; आप केवल अपने सर्वलेट को आपके द्वारा बनाए गए यूआरएल के लिए छवियों की सेवा करना चाहते हैं। इसलिए, जब आप url बनाते हैं, तो गणना करें md5(image_url + secret_key)और इसे हैश पैरामीटर के रूप में जोड़ें। इससे पहले कि आप अनुरोध परोसें, हैश को पुनः स्थापित करें और इसकी तुलना करें कि आपको क्या पारित किया गया था। चूंकि secret_key केवल आपके लिए जाना जाता है, कोई और मान्य url का निर्माण नहीं कर सकता है।

यदि आप जावा में विकसित कर रहे हैं, तो सर्वलेट कोड की कुछ पंक्तियाँ हैं। आपको किसी अन्य बैक-एंड तकनीक पर नीचे दिए गए कोड को पोर्ट करने में सक्षम होना चाहिए।

/*
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);
    }    
}

1
बहुत ध्वनि, और मुझे लगता है कि यह वही है जिसके साथ मैं रोल करूंगा। हम PHP का उपयोग कर रहे हैं, लेकिन कार्यान्वयन भी तुच्छ होगा। मैं अपनी तरफ से कैशिंग भी लागू करूंगा, क्योंकि मैं हर बार किसी से यह अनुरोध करने के लिए छवि को डाउनलोड नहीं करना चाहता (प्रदर्शन और बैंडवाथ उपयोग के लिए)। सुरक्षा दृष्टिकोण के लिए सुझाव ध्वनि हैं (हालांकि हम अपने मानक सुरक्षा मॉडल के साथ-साथ ऊपर भी लागू करेंगे)। तुम्हारे सुझाव के लिए धन्यवाद।
एल योबो

32
इस दृष्टिकोण के लिए केवल गंभीर नकारात्मक पक्ष यह है कि आप अपने स्वयं के सिस्टम के माध्यम से सभी बाहरी संसाधनों को पार कर रहे हैं। जो न केवल एक दायित्व है, बल्कि महंगा भी हो सकता है।
टिम मोलेंडीजक

मैं दूसरा @TimMolendijk, यह कहते हुए कि यह न केवल लागत और रखरखाव को जोड़ता है, बल्कि किसी भी CDN को भी पराजित करता है, जिसे सर्वर के पास या निष्क्रिय करने के लिए संतुलन के लिए मार्ग माना जाता है।
लेवेंटे PANczél

2
NodeJS के लिए क्या उपाय है?
stkvtflw

1
@TimMolendijk के लिए एक और +1 लेकिन फिर समाधान क्या होगा? HTTPS से अधिक साइट पर HTTP के माध्यम से दी गई छवियों के साथ अच्छी तरह से खेलने के लिए प्रतीत नहीं होता है
FullStackForger

15

यदि आप HTTPS पर छवियों को लोड करने के लिए एक त्वरित समाधान की तलाश कर रहे हैं तो https://images.weserv.nl/ पर मुफ्त रिवर्स प्रॉक्सी सेवा आपको रुचि दे सकती है। मुझे ठीक इसी की तलाश थी।

यदि आप सशुल्क समाधान की तलाश कर रहे हैं, तो मैंने पहले Cloudinary.com का उपयोग किया है जो अच्छी तरह से काम करता है, लेकिन इस कार्य के लिए बहुत महंगा है, मेरी राय में।


क्या चालबाजी है? महान काम करता है
जैक

5
@JackNicholson मैं इसे 2 साल के लिए अपेक्षाकृत भारी भार के तहत उपयोग कर रहा हूं। बहुत अच्छा काम करता है! कुदोस दो देवों को।
nullable

मेरे पास Http से शुरू होने वाले कुछ लिंक (वीडियो या साइट) हैं और मैं उन्हें हमारे https साइट पर एक iframe में प्रदर्शित करने में असमर्थ हूं। के रूप में यह बकवास लिंक है यह काम नहीं कर रहा है। एक छवि के लिए, मैंने छवि कैश का उपयोग करके समस्या हल कर ली है। किसी को भी कोई विचार है
int14

@ int14 आपको http साइट के लिए एक रिवर्स प्रॉक्सी सेट करने की आवश्यकता होगी, आप ऐसा कुछ AWS API गेटवे के साथ कर सकते हैं।
नल

3

मुझे नहीं पता कि यह आपके लिए उपयुक्त है या नहीं, लेकिन एक त्वरित समाधान के रूप में मैं http सामग्री को एक https स्क्रिप्ट में "लपेट" दूंगा। उदाहरण के लिए, आपके पेज पर जिसे मैं https के माध्यम से परोसा जाता है, एक iframe पेश करेगा जो आपके rss फ़ीड को बदल देगा और iframe के src attr में आपके सर्वर पर एक स्क्रिप्ट का url डाल देगा जो फ़ीड को कैप्चर करता है और html को आउटपुट करता है। स्क्रिप्ट http के माध्यम से फ़ीड पढ़ रहा है और इसे https के माध्यम से आउटपुट करता है (इस प्रकार "रैपिंग")

सिर्फ एक विचार


ऐसा लगता है कि यह मुझे उसी स्थिति में छोड़ देगा जैसा मैं अभी हूं; मैं पहले से ही HTTPS पेज में सामग्री दिखा रहा हूं - समस्या यह है कि http: // src मानों के साथ सामग्री में <img> टैग हैं - जो दिखाए नहीं जाते हैं और एक कष्टप्रद संदेश उत्पन्न करते हैं।
एल योबो

ठीक है, हाँ, यदि आप छवियों के मूल लिंक रखते हैं, तो समस्या से बचने का कोई तरीका नहीं है। आवरण स्क्रिप्ट को छवियों के लिए आरएसएस फ़ीड सामग्री को स्कैन करना होगा और उन को हटाना होगा। जैसा कि आपने एक अन्य टिप्पणी में उल्लेख किया है - आप उस सामग्री को लोड नहीं करना चाहते हैं जो पॉपअप का कारण बनती है और इसके बजाय कुछ जानकारीपूर्ण दिखाती है। यही कारण है कि "बीच में स्क्रिप्ट"
hndcrftd

आप अपने मुख्य बैकएंड स्क्रिप्ट में, बिना iframe के भी ऐसा कर सकते हैं, लेकिन इस मामले में आप किसी पृष्ठ पर संसाधित और आउटपुट होने से पहले rss फ़ीड के वापस आने का इंतजार कर रहे हैं। मैं एक iFrame करूंगा ताकि आपका पृष्ठ rss फ़ीड के साथ अतुल्यकालिक रूप से लोड हो। यदि आप आइफ्रेम से बचने के लिए वहां जाना चाहते हैं तो भी ajax विकल्प है। बस जिज्ञासु - आपका बैकएंड प्लेटफॉर्म क्या है?
hndcrftd

2

अपनी दूसरी आवश्यकता के बारे में - आप ऑनरर ईवेंट का उपयोग करने में सक्षम हो सकते हैं, अर्थात। <img onerror="some javascript;"...

अपडेट करें:

तुम भी document.imagesडोम में के माध्यम से पुनरावृत्ति की कोशिश कर सकते हैं । एक completeबूलियन संपत्ति है जिसे आप उपयोग करने में सक्षम हो सकते हैं। मैं यह सुनिश्चित करने के लिए नहीं जानता कि यह उपयुक्त होगा, लेकिन जांच के लायक हो सकता है।


दिलचस्प है, मैं यह भी नहीं जानता था कि वहाँ एक onerror घटना थी। मुझे HTML को फिर से लिखना होगा (जैसा कि यह एक बाहरी स्रोत से आ रहा है), लेकिन यह पहले से ही HTML शोधक के साथ साफ किया जा रहा है, इसलिए फ़िल्टर के रूप में जोड़ना संभव हो सकता है।
एल योबो

जावास्क्रिप्ट को कुछ भी करने का मौका देने से पहले कोई भी ब्राउज़र सुरक्षा चेतावनी नहीं होगी ?
मृद्वीथ

0

यह सबसे अच्छा होगा बस https पर http कंटेंट हो


5
यदि मैंने अपने प्रश्न में यह स्पष्ट नहीं किया है, तो HTTP सामग्री अन्य लोगों के सर्वर पर नहीं है। विशेष रूप से, यह HTML में <img> लिंक है जिसे मैंने RSS फ़ीड से पुनर्प्राप्त किया है। मैंने अब इस प्रश्न पर जोर दिया है।
एल योबो

ओह ठीक है, webproworld.com/webmaster-forum/threads/… सब पर मदद करेगा ?
डैनियल

0

कभी-कभी फेसबुक ऐप्स की तरह हम सुरक्षित पेज में गैर-सुरक्षित सामग्री नहीं रख सकते। इसके अलावा, हम उन सामग्रियों को स्थानीय नहीं बना सकते हैं। उदाहरण के लिए एक ऐप जो iFrame में लोड होगा वह एक साधारण सामग्री नहीं है और हम इसे स्थानीय नहीं बना सकते हैं।

मुझे लगता है कि हमें कभी भी http कंटेंट को https में लोड नहीं करना चाहिए, साथ ही हमें एरर डायलॉग को रोकने के लिए https पेज को http वर्जन पर वापस नहीं करना चाहिए।

एकमात्र तरीका जो उपयोगकर्ता की सुरक्षा सुनिश्चित करेगा, वह सभी सामग्रियों के https संस्करण, http://developers.facebook.com/blog/post/499/ का उपयोग करेगा।


3
यह फेसबुक के साथ संभव हो सकता है, लेकिन सभी सामग्री के लिए नहीं और यह सवाल फेसबुक के बारे में नहीं था।
एल योबो

0

स्वीकृत उत्तर ने मुझे 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 ?>" />

जावास्क्रिप्ट / 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>

images.php देखें http://stackoverflow.com/questions/8719276/cors-with-php-headers?noredirect=1&lq=1 for 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;
}

-2

बस: यह मत करो। HTTPS पेज के भीतर Http कंटेंट स्वाभाविक रूप से असुरक्षित है। बिंदु। यही कारण है कि IE एक चेतावनी दिखाता है। चेतावनी से छुटकारा पाना एक मूर्ख हॉगवाश दृष्टिकोण है।

इसके बजाय, एक HTTPS पेज ही चाहिए HTTPS सामग्री । सुनिश्चित करें कि सामग्री को HTTPS के माध्यम से भी लोड किया जा सकता है, और इसे https के माध्यम से संदर्भित करें यदि पृष्ठ को https के माध्यम से लोड किया गया है। बाहरी सामग्री के लिए इसका मतलब स्थानीय स्तर पर तत्वों को लोड करना और कैशिंग करना होगा ताकि वे https - ज़रूर उपलब्ध हों। उसके आसपास कोई रास्ता नहीं, दुख की बात है।

चेतावनी एक अच्छे कारण के लिए है। गंभीरता से। 5 मिनट यह सोचकर खर्च करें कि आप कस्टम सामग्री के साथ https दिखाए गए पृष्ठ पर कैसे ले जा सकते हैं - आपको आश्चर्य होगा।


3
वहां आसान है, मुझे पता है कि इसके लिए एक अच्छा कारण है; मुझे लगता है कि IE का व्यवहार इस संबंध में FF से बेहतर है। जो मैं लक्ष्य कर रहा हूं वह सामग्री को लोड करने के लिए नहीं है; मैं केवल घुसपैठ पॉपअप शैली की चेतावनी से बचना चाहता हूं और सामग्री के स्थान पर कुछ जानकारीपूर्ण दिखाना चाहता हूं।
एल योबो

2
उसके लिए कोई मौका नहीं - जब तक कि आप बाहर के रास्ते पर HTML को फिर से नहीं लिखेंगे। किसी भी जावास्क्रिप्ट पोस्ट लोड प्रयास ने पहले ही संवाद दिखाया है।
टॉमटॉम

वह सिर्फ छवियों के बारे में पूछ रहा था और वह किसी भी असुरक्षित पाठ या स्क्रिप्ट का अनुरोध नहीं कर रहा है, इसलिए हम यूआरएल को फिर से लिखकर चेतावनी पारित कर सकते हैं।
जयपाल चंद्रन

1
जवाब में कोई बदलाव नहीं। छवियां असुरक्षित भी हो सकती हैं। यह एक सामान्य बात है - या तो यह सुरक्षित स्रोत से आ रहा है, मध्य आक्रमण में एक आदमी द्वारा प्रतिस्थापित किया जा सकता है।
TomTom

8
नीच क्योंकि यह "उत्तर" ओपी के लक्ष्य को प्राप्त करने के लिए कैसे जवाब नहीं दिया।
माइकस्किंकेल

-3

मुझे एहसास है कि यह एक पुराना धागा है, लेकिन एक विकल्प सिर्फ http: part को इमेज URL से निकालने का है ताकि ' http: //some/image.jpg ' ' //some/image.jpg ' बन जाए। यह CDN के साथ भी काम करेगा


7
यह कभी-कभी काम करेगा और कभी-कभी नहीं; यह निर्भर करता है कि HTTPS के माध्यम से अपस्ट्रीम सामग्री उपलब्ध है या नहीं। यदि नहीं, तो यह बस टूट जाएगा।
एल योबो

-3

मेरे लिए सबसे अच्छा तरीका है काम

<img src="/path/image.png" />// this work only online
    or
    <img src="../../path/image.png" /> // this work both
    or asign variable
    <?php 
    $base_url = '';
    if($_SERVER['HTTP_HOST'] == 'localhost')
    {
         $base_url = 'localpath'; 
    }
    ?>
    <img src="<?php echo $base_url;?>/path/image.png" /> 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.