2012-03-08 8 views
11

मैंने फिडलर पर ध्यान दिया कि [RequHttps] स्थिति कोड 302 के बजाय 302 रीडायरेक्ट करता है। मुझे यकीन नहीं है कि यह कैसे समझ में आता है ...एमवीसी में [RequHttps] नहीं होना चाहिए 301 स्थायी पुनर्निर्देशन? यह 302 (एसईओ के लिए बुरा क्यों है?)

यदि आप हैं यह कहते हुए कि एक नियंत्रक [RequHttps], तो आप कभी भी कभी नहीं चाहते कि लोग उस पृष्ठ के एचटीपी संस्करण पर जाएं। तो स्थायी रीडायरेक्ट क्यों नहीं है ... खोज इंजन को बताएं "कृपया इस पृष्ठ के https संस्करण में स्थायी रूप से अपने लिंक अपडेट करें"।

यदि यह समझ में आता है, और मैं सही हूं, तो इसे 301 रीडायरेक्ट में बदलने का कोई तरीका है?

+1

http://webmasters.stackexchange.com/questions/22268/when-redirecting-from-http-to-https-in-a-shop-site-which-status-code-should-iu – Hupperware

उत्तर

7

ऐसा लगता है कि 302 से अधिक 301 के साथ जाने का विकल्प शुरू करने के लिए थोड़ा मनमाना था। हालांकि, यह जरूरी नहीं है कि प्रत्येक यूआरएल एचटीटीपीएस योजना का उपयोग करने के लिए "है" जा रहा है। वहां बहुत अच्छा पृष्ठ हो सकता है जो HTTP या HTTPS दोनों से पहुंच की अनुमति देता है भले ही वह बाद वाले को प्रोत्साहित कर सके। एक कार्यान्वयन जहां यह हो सकता है, कुछ विशेष मानदंडों के आधार पर HTTPS का उपयोग करना है या नहीं, यह निर्धारित करने के लिए कुछ कोड वायर्ड हो सकते हैं।

एक केस परिदृश्य के रूप में, जीमेल पर एक नज़र डालें। सेटिंग्स के भीतर, एप्लिकेशन के बड़े हिस्सों में HTTPS प्रोटोकॉल को अनुमति देने या अस्वीकार करने में सक्षम है। तब कौन सा कोड वापस किया जाना चाहिए? 301 सटीक नहीं होगा, क्योंकि यह "स्थायी" नहीं है ... उपयोगकर्ता के आदेश पर केवल एक बदलाव है। अफसोस की बात है, 302 बिल्कुल सटीक नहीं है क्योंकि 302 त्रुटि का तात्पर्य है कि भविष्य में किसी बिंदु पर लिंक को वापस बदलने का इरादा है (संबंधित संदर्भ http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)।

अनुमोदित, जीमेल एक मोटा उदाहरण है क्योंकि साइट के उन हिस्सों का हिस्सा जो आमतौर पर एक खोज इंजन द्वारा अनुक्रमित नहीं होते हैं, लेकिन संभावना अभी भी मौजूद है।

और अपने अंतिम प्रश्न का उत्तर देने के लिए, यदि आप एएसपी.नेट एमवीसी (जो मुझे लगता है कि आप छोटे वाक्यविन्यास उदाहरण से उपयोग कर रहे हैं) में एक अलग स्थिति कोड चाहते हैं, तो एक सरल, कस्टम विशेषता के साथ बदलना संभव है:

public class MyRequireHttpsAttribute : RequireHttpsAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     base.OnAuthorization(filterContext); 

     if (!filterContext.HttpContext.Request.IsSecureConnection) 
      filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.MovedPermanently; 
    } 
} 

अब सभी कार्यों उस गुण को लागू एक 301 स्थिति कोड जब HTTP प्रोटोकॉल के माध्यम से सुलभ लौटना चाहिए।

+3

RequHttps विशेषता एक विशेषता नहीं है जो इस मामले में किसी भी "पसंद" को छोड़ देती है। यह मूल रूप से कह रहा है * HTTPS होना चाहिए - HTTP गलत है * क्योंकि HTTP पर साइट पर जाना असंभव है। यही कारण है कि मुझे लगता है कि यह वास्तव में शुरू करने के लिए 301 होना चाहिए था ... लेकिन आपका कोड स्पॉट-ऑन है और मैं चर्चा की सराहना करता हूं। इससे पहले कि मैं इसे 301 पर स्विच करने का फैसला करता हूं, मैं थोड़ी अधिक शोध करूँगा ... मैं एसईओ के लिए थोड़ा नया हूं। धन्यवाद! –

+1

ठीक है, और मैं विशेष रूप से RequHttps विशेषता पर उस बिंदु से सहमत हूं। मैं एक विशेष ढांचे के संदर्भ के बाहर किसी विशेष अनुप्रयोग में स्पष्ट रूप से आवश्यक नहीं है, इस बारे में बड़ी तस्वीर प्राप्त करने की कोशिश कर रहा था। खुशी हुई कोड ने मदद की! – Dulan

+4

दुर्भाग्यवश यह काम नहीं किया ... यह अभी भी 302 करता है। मैंने इसके साथ गड़बड़ करने की कोशिश की ... लेकिन मैं अभी भी RequHttps को ओवरराइड नहीं कर सका और इसे 301 कर सकता हूं। इसके बजाय, मैंने अभी अपना खुद का [RequHttpsPerm] बनाया है और खुद को रीडायरेक्ट कर रहा हूं। –

4

डुलन के समाधान ने मुझे सही रास्ते पर रखा, लेकिन कोड नमूना कोर RequHttpsAttribute कार्यान्वयन से 302 रीडायरेक्ट को रोक नहीं पाया। इसलिए, मैंने RequHttpsAttribute के कोड को देखा और इसे हैक किया। यहाँ है कि मैं क्या के साथ आया है:

using System.Net; 
using System.Web.Mvc; 
using System; 
using System.Diagnostics.CodeAnalysis; 

[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "Unsealed because type contains virtual extensibility points.")] 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
public class RequireHttps301Attribute : FilterAttribute, IAuthorizationFilter 
{ 

    public virtual void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (filterContext == null) { 
      throw new ArgumentNullException("filterContext"); 
     } 

     if (!filterContext.HttpContext.Request.IsSecureConnection) { 
      HandleNonHttpsRequest(filterContext); 
     } 
    } 

    protected virtual void HandleNonHttpsRequest(AuthorizationContext filterContext) 
    { 
     // only redirect for GET requests, otherwise the browser might not propagate the verb and request 
     // body correctly. 

     if (!String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) { 
      throw new InvalidOperationException("Only redirect for GET requests, otherwise the browser might not propagate the verb and request body correctly."); 
     } 

     // redirect to HTTPS version of page 
     string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl; 
     //what mvc did to redirect as a 302 
     //filterContext.Result = new RedirectResult(url); 

     //what I did to redirect as a 301 
     filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.MovedPermanently; 
     filterContext.HttpContext.Response.RedirectLocation = url; 
    } 
} 
+1

मुझे एमवीसी 4+ के साथ विश्वास है, आप 'रीडायरेक्ट रीसेट' कन्स्ट्रक्टर का उपयोग कर सकते हैं जो 2 तर्क लेता है और 301 को मजबूर करता है: 'filterContext.Result = new RedirectResult (url, true); ' –

8

Dulan के जवाब करीब है, लेकिन यह काम नहीं करता है, कम से कम हमारे MVC 4 समाधान के साथ। लेकिन कुछ परीक्षण और त्रुटि के बाद, हमने 302 के बजाय 301 के साथ काम किया। यहाँ नया वर्ग है:

public class CustomRequireHttpsAttribute : RequireHttpsAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     #if !DEBUG 
     base.OnAuthorization(filterContext); 

     if (!filterContext.HttpContext.Request.IsSecureConnection) 
     { 
      string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl; 
      filterContext.Result = new RedirectResult(url, true); 
     } 
     #endif 
    } 
} 

कारण Dulan का जवाब काम नहीं किया हो सकता है क्योंकि filterContext.Result की Permanent संपत्ति केवल पढ़ने के लिए है और केवल उसी RedirectResult() कहा जाता है सेट किया जा सकता है, और समस्या यह है लगता है RedirectResult() को base.OnAuthorization() विधि में बुलाया जाता है। तो बस मूल विधि को कॉल करें, फिर परिणाम को स्थायी बनाने के लिए सत्य के दूसरे पैरामीटर के साथ नीचे filterContext.Result ओवरराइड करें। ऐसा करने के बाद, हमने फिडलर 2 में 301 कोड देखना शुरू कर दिया।

1

बस एक त्वरित नोट है कि अनुरोध HttpsAttribute भी एक अवैधऑपरेशन अपवाद फेंकता है यदि अनुरोध कुछ भी है लेकिन अनुरोध प्राप्त है। यह 405 विधि अनुमत नहीं लौटाकर बेहतर सेवा प्रदान करता है, जो कि एक और अधिक उचित त्रुटि है।

नीचे दिए गए मेरे कार्यान्वयन में, मैं विशेषता का उपयोगकर्ता भी विकल्प देता हूं कि वे स्थायी रूप से (301) या अस्थायी रूप से (302) रीडायरेक्ट करना चाहते हैं या नहीं। जैसा कि @ डुलन ने कहा था, यदि आपको एचटीटीपीएस द्वारा पृष्ठ तक कभी भी पहुंचा जा सकता है और 302 अस्थायी रीडायरेक्ट किया जा सकता है तो पृष्ठ को 301 स्थायी रीडायरेक्ट करना चाहिए यदि पृष्ठ को HTTP या HTTPS पर पहुंचा जा सकता है।

/// <summary> 
/// Represents an attribute that forces an unsecured HTTP request to be re-sent over HTTPS. 
/// <see cref="System.Web.Mvc.RequireHttpsAttribute"/> performs a 302 Temporary redirect from a HTTP URL to a HTTPS URL. 
/// This filter gives you the option to perform a 301 Permanent redirect or a 302 temporary redirect. 
/// You should perform a 301 permanent redirect if the page can only ever be accessed by HTTPS and a 302 temporary redirect if 
/// the page can be accessed over HTTP or HTTPS. 
/// </summary> 
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] 
public class RedirectToHttpsAttribute : FilterAttribute, IAuthorizationFilter 
{ 
    private readonly bool permanent; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="RedirectToHttpsAttribute"/> class. 
    /// </summary> 
    /// <param name="permanent">if set to <c>true</c> the redirection should be permanent; otherwise, <c>false</c>.</param> 
    public RedirectToHttpsAttribute(bool permanent) 
    { 
     this.permanent = permanent; 
    } 

    /// <summary> 
    /// Gets a value that indicates whether the redirection should be permanent. 
    /// </summary> 
    /// <value> 
    /// <c>true</c> if the redirection should be permanent; otherwise, <c>false</c>. 
    /// </value> 
    public bool Permanent 
    { 
     get { return this.permanent; } 
    } 

    /// <summary> 
    /// Determines whether a request is secured (HTTPS) and, if it is not, calls the <see cref="HandleNonHttpsRequest"/> method. 
    /// </summary> 
    /// <param name="filterContext">An object that encapsulates information that is required in order to use the <see cref="System.Web.Mvc.RequireHttpsAttribute"/> attribute.</param> 
    /// <exception cref="System.ArgumentNullException">The filterContext parameter is null.</exception> 
    public virtual void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (filterContext == null) 
     { 
      throw new ArgumentNullException("filterContext"); 
     } 

     if (!filterContext.HttpContext.Request.IsSecureConnection) 
     { 
      this.HandleNonHttpsRequest(filterContext); 
     } 
    } 

    /// <summary> 
    /// Handles unsecured HTTP requests that are sent to the action method. 
    /// </summary> 
    /// <param name="filterContext">An object that encapsulates information that is required in order to use the <see cref="System.Web.Mvc.RequireHttpsAttribute"/> attribute.</param> 
    /// <exception cref="System.InvalidOperationException">The HTTP request contains an invalid transfer method override. All GET requests are considered invalid.</exception> 
    protected virtual void HandleNonHttpsRequest(AuthorizationContext filterContext) 
    { 
     // Only redirect for GET requests, otherwise the browser might not propagate the verb and request body correctly. 
     if (!string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) 
     { 
      // The RequireHttpsAttribute throws an InvalidOperationException. Some bots and spiders make HEAD requests (to reduce bandwidth) 
      // and we don’t want them to see a 500-Internal Server Error. A 405 Method Not Allowed would be more appropriate. 
      throw new HttpException((int)HttpStatusCode.MethodNotAllowed, "Method Not Allowed"); 
     } 

     string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl; 
     filterContext.Result = new RedirectResult(url, this.permanent); 
    } 
} 
संबंधित मुद्दे