apache - Mod_rewrite की छिपी हुई विशेषताएं




.htaccess mod-rewrite (6)

ऐसा लगता है कि इसके कुछ पहलुओं कैसे काम करते हैं, इस बारे में कुछ भ्रम के साथ हाल ही में mod_rewrite धागे की एक सभ्य संख्या है। नतीजतन मैंने सामान्य कार्यक्षमता पर कुछ नोट्स संकलित किए हैं, और शायद कुछ कष्टप्रद बारीकियां।

mod_rewrite का उपयोग करके आप किन अन्य सुविधाओं / सामान्य मुद्दों को चलाते हैं?


Mod_rewrite नियम कहां रखें

mod_rewrite नियम httpd.conf फ़ाइल में या .htaccess फ़ाइल के भीतर रखा जा सकता है। अगर आपके पास httpd.conf तक पहुंच है, तो यहां नियमों को एक प्रदर्शन लाभ प्रदान करेगा (क्योंकि नियमों को एक बार संसाधित किया जाता है, क्योंकि प्रत्येक बार .htaccess फ़ाइल को कॉल किया जाता है)।

Mod_rewrite अनुरोध लॉगिंग

लॉगिंग httpd.conf फ़ाइल ( <Virtual Host> सहित) के भीतर से सक्षम की जा सकती है:

# logs can't be enabled from .htaccess
# loglevel > 2 is really spammy!
RewriteLog /path/to/rewrite.log
RewriteLogLevel 2

सामान्य उपयोग के मामले

  1. सभी अनुरोधों को एक बिंदु पर फ़नल करने के लिए:

    RewriteEngine on
    # ignore existing files
    RewriteCond %{REQUEST_FILENAME} !-f   
    # ignore existing directories
    RewriteCond %{REQUEST_FILENAME} !-d   
    # map requests to index.php and append as a query string
    RewriteRule ^(.*)$ index.php?query=$1 
    

    अपाचे 2.2.16 के बाद से आप FallbackResource भी उपयोग कर सकते हैं।

  2. 301/302 रीडायरेक्ट हैंडलिंग:

    RewriteEngine on
    # 302 Temporary Redirect (302 is the default, but can be specified for clarity)
    RewriteRule ^oldpage\.html$ /newpage.html [R=302]  
    # 301 Permanent Redirect
    RewriteRule ^oldpage2\.html$ /newpage.html [R=301] 
    

    नोट : बाहरी रीडायरेक्ट निश्चित रूप से 302 रीडायरेक्ट हैं:

    # this rule:
    RewriteRule ^somepage\.html$ http://google.com
    # is equivalent to:
    RewriteRule ^somepage\.html$ http://google.com [R]
    # and:
    RewriteRule ^somepage\.html$ http://google.com [R=302]
    
  3. एसएसएल मजबूर करना

    RewriteEngine on
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://example.com/$1 [R,L]
    
  4. सामान्य झंडे:

    • [R] या [redirect] - एक रीडायरेक्ट को मजबूर करें (302 अस्थायी रीडायरेक्ट पर डिफ़ॉल्ट)
    • [R=301] या [redirect=301] - एक 301 स्थायी पुनर्निर्देशन को मजबूर करें
    • [L] या [last] - पुनर्लेखन प्रक्रिया रोकें (सामान्य नुकसान में नीचे नोट देखें)
    • [NC] या [nocase] - निर्दिष्ट करें कि मिलान केस असंवेदनशील होना चाहिए


    झंडे के लंबे रूप का उपयोग अक्सर अधिक पठनीय होता है और बाद में आपके कोड को पढ़ने वाले अन्य लोगों की सहायता करेगा।

    आप अल्पविराम के साथ एकाधिक झंडे अलग कर सकते हैं:

    RewriteRule ^olddir(.*)$ /newdir$1 [L,NC]
    

आम नुकसान

  1. mod_alias साथ mod_alias शैली रीडायरेक्ट मिश्रण

    # Bad
    Redirect 302 /somepage.html http://example.com/otherpage.html
    RewriteEngine on
    RewriteRule ^(.*)$ index.php?query=$1
    
    # Good (use mod_rewrite for both)
    RewriteEngine on
    # 302 redirect and stop processing
    RewriteRule ^somepage.html$ /otherpage.html [R=302,L] 
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    # handle other redirects
    RewriteRule ^(.*)$ index.php?query=$1                 
    

    नोट : आप mod_rewrite साथ mod_alias को मिश्रित कर सकते हैं, लेकिन इसमें ऊपर के रूप में मूल रीडायरेक्ट को संभालने से अधिक काम शामिल है।

  2. संदर्भ वाक्यविन्यास को प्रभावित करता है

    .htaccess फ़ाइलों के भीतर, रिवाइटरूल पैटर्न में एक प्रमुख स्लैश का उपयोग नहीं किया जाता है:

    # given: GET /directory/file.html
    
    # .htaccess
    # result: /newdirectory/file.html
    RewriteRule ^directory(.*)$ /newdirectory$1
    
    # .htaccess
    # result: no match!
    RewriteRule ^/directory(.*)$ /newdirectory$1
    
    # httpd.conf
    # result: /newdirectory/file.html
    RewriteRule ^/directory(.*)$ /newdirectory$1
    
    # Putting a "?" after the slash will allow it to work in both contexts:
    RewriteRule ^/?directory(.*)$ /newdirectory$1
    
  3. [एल] आखिरी नहीं है! (कभी कभी)

    [L] ध्वज नियम सेट के माध्यम से उस पास के लिए किसी और पुनः लिखने के नियमों को संसाधित करना बंद कर देता है। हालांकि, अगर उस पास यूआरएल को उस पास में संशोधित किया गया था और आप .htaccess संदर्भ या <Directory> अनुभाग में हैं, तो आपका संशोधित अनुरोध यूआरएल पार्सिंग इंजन के माध्यम से फिर से पारित किया जा रहा है। और अगले पास, यह इस समय एक अलग नियम से मेल खा सकता है। यदि आप इसे नहीं समझते हैं, तो ऐसा लगता है कि आपके [L] ध्वज का कोई प्रभाव नहीं पड़ा।

    # processing does not stop here
    RewriteRule ^dirA$ /dirB [L] 
    # /dirC will be the final result
    RewriteRule ^dirB$ /dirC     
    

    हमारे पुनर्लेखन लॉग से पता चलता है कि नियम दो बार चलाए जाते हैं और यूआरएल दो बार अपडेट किया जाता है:

    rewrite 'dirA' -> '/dirB'
    internal redirect with /dirB [INTERNAL REDIRECT]
    rewrite 'dirB' -> '/dirC'
    

    [L] ध्वज के बजाय [END] ध्वज ( अपाचे डॉक्स देखें ) का उपयोग करने के लिए इसका सबसे अच्छा तरीका है, यदि आप वास्तव में नियमों के सभी प्रसंस्करण (और बाद के पास) को रोकना चाहते हैं। हालांकि, [END] ध्वज केवल अपाचे v2.3.9 + के लिए उपलब्ध है, इसलिए यदि आपके पास v2.2 या इससे कम है, तो आप केवल [L] ध्वज के साथ फंस गए हैं।

    पिछले संस्करणों के लिए, आपको यूआरएल पार्सिंग इंजन के बाद के पासों पर नियमों के मिलान को रोकने के लिए RewriteCond कथन पर भरोसा करना चाहिए।

    # Only process the following RewriteRule if on the first pass
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ...
    

    या आपको यह सुनिश्चित करना होगा कि आपका रिवाइटरूल एक संदर्भ में है (यानी httpd.conf ) जो आपके अनुरोध को फिर से पारदर्शी नहीं करेगा।


[एल] ध्वज की बेहतर समझ क्रम में है। [एल] ध्वज आखिरी है, आपको बस यह समझना होगा कि यूआरएल पार्सिंग इंजन के माध्यम से आपके अनुरोध को फिर से रूट करने का क्या कारण होगा। दस्तावेज़ों से ( http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l ) (जोर मेरा):

[एल] ध्वज नियम सेट को संसाधित करना बंद करने के लिए mod_rewrite का कारण बनता है। अधिकांश संदर्भों में, इसका मतलब है कि यदि नियम मेल खाता है, तो कोई और नियम संसाधित नहीं किया जाएगा। यह पर्ल में अंतिम आदेश, या सी में ब्रेक कमांड से मेल खाता है। इस ध्वज का उपयोग यह इंगित करने के लिए करें कि वर्तमान नियम तुरंत नियमों पर विचार किए बिना लागू किया जाना चाहिए।

यदि आप किसी भी। Htaccess फ़ाइलों में या <Directory> अनुभागों में RewriteRule का उपयोग कर रहे हैं, तो नियमों को संसाधित करने के तरीके के बारे में कुछ समझना महत्वपूर्ण है। इसका सरलीकृत रूप यह है कि नियमों को संसाधित करने के बाद, पुनः लिखा अनुरोध यूआरएल पार्सिंग इंजन को सौंप दिया जाता है ताकि वह इसके साथ क्या कर सके। यह संभव है कि पुनर्लेखन अनुरोध को संभाला जा सके, .htaccess फ़ाइल या <Directory> अनुभाग का फिर से सामना किया जा सकता है, और इस प्रकार नियमसेट को शुरुआत से फिर से चलाया जा सकता है। आमतौर पर यह तब होगा जब नियमों में से एक रीडायरेक्ट का कारण बनता है - या तो आंतरिक या बाहरी - अनुरोध प्रक्रिया शुरू होने का कारण बनता है।

इसलिए [एल] ध्वज नियम सेट के माध्यम से उस पास के लिए किसी और पुनः लिखने के नियमों को संसाधित करना बंद कर देता है । हालांकि, यदि आपका नियम [एल] के साथ चिह्नित है, तो अनुरोध को संशोधित किया गया है, और आप .htaccess संदर्भ या <Directory> अनुभाग में हैं, तो आपका संशोधित अनुरोध URL पार्सिंग इंजन के माध्यम से फिर से पारित किया जा रहा है। और अगले पास, यह इस समय एक अलग नियम से मेल खा सकता है। यदि आपको समझ में नहीं आता कि क्या हुआ, तो ऐसा लगता है कि [एल] ध्वज के साथ आपका पहला पुनर्लेखन नियम कोई प्रभाव नहीं पड़ा।

[एल] ध्वज के बजाय [END] ध्वज ( http://httpd.apache.org/docs/current/rewrite/flags.html#flag_end ) का उपयोग करने के लिए इसका सबसे अच्छा तरीका है, अगर आप वास्तव में रुकना चाहते हैं नियमों के सभी आगे प्रसंस्करण (और बाद में reparsing)। हालांकि, [END] ध्वज केवल अपाचे v2.3.9 + के लिए उपलब्ध है, इसलिए यदि आपके पास v2.2 या इससे कम है, तो आप केवल [एल] ध्वज के साथ फंस गए हैं। इस मामले में, आपको यूआरएल पार्सिंग इंजन के बाद के पासों पर नियमों के मिलान को रोकने के लिए रिवाइटकंड स्टेटमेंट पर भरोसा करना चाहिए। या आपको यह सुनिश्चित करना होगा कि आपका रिवाइटरूल एक संदर्भ में है (यानी httpd.conf) जो आपके अनुरोध को फिर से पारदर्शी नहीं करेगा।


एक और महान विशेषता पुनर्लेखन-मानचित्र-विस्तार हैं। वे विशेष रूप से उपयोगी होते हैं यदि आपके पास होस्ट करने के लिए होस्ट / रीराइट्स का भारी हिस्सा है:

वे एक महत्वपूर्ण मूल्य-प्रतिस्थापन की तरह हैं:

RewriteMap examplemap txt:/path/to/file/map.txt

फिर आप अपने नियमों में मैपिंग का उपयोग कर सकते हैं जैसे:

RewriteRule ^/ex/(.*) ${examplemap:$1}

इस विषय पर अधिक जानकारी यहां मिल सकती है:

http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#mapfunc


यदि आपको .htaccess में होने से आंतरिक रीडायरेक्ट / पुनर्लेखन को 'अवरुद्ध' करने की आवश्यकता है, तो एक नज़र डालें

RewriteCond %{ENV:REDIRECT_STATUS} ^$

जैसा कि यहां चर्चा की गई है


अन्य नुकसान:

1- कभी-कभी मल्टीव्यू को अक्षम करना अच्छा विचार है

Options -MultiViews

मैं सभी मल्टीव्यू क्षमताओं पर अच्छी तरह से कविता नहीं हूं, लेकिन मुझे पता है कि यह सक्रिय होने पर मेरे mod_rewrite नियमों को गड़बड़ कर देता है, क्योंकि इसकी एक संपत्ति एक फ़ाइल को एक एक्सटेंशन का अनुमान लगाने और अनुमान लगाने के लिए है जिसे मैं सोचता हूं ।

मैं समझाऊंगा: मान लें कि आपके पास अपने वेब डीआईआर, file1.php और file2.php में 2 php फ़ाइलें हैं और आप इन शर्तों को जोड़ते हैं और अपने .htaccess पर नियम डालते हैं:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ file1.php/$1 

आप मानते हैं कि सभी यूआरएल जो फ़ाइल या निर्देशिका से मेल नहीं खाते हैं उन्हें file1.php द्वारा पकड़ा जाएगा। आश्चर्य! यूआरएल http://myhost/file2/somepath लिए यह नियम सम्मानित नहीं किया जा रहा है। इसके बजाय आपको file2.php के अंदर ले जाया गया है।

क्या हो रहा है कि http://myhost/file2.php/somepath ने http://myhost/file2.php/somepath से अनुमान लगाया है कि आप जिस यूआरएल को वास्तव में चाहते थे वह http://myhost/file2.php/somepath और खुशी से आपको वहां ले गया।

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

ठीक है, संक्षेप में यदि आप mod_rewrite को ऐसे तरीके से काम करना चाहते हैं जो तर्क को अनुमानित करता है, तो मल्टीव्यूज़ को बंद करना सही दिशा में एक कदम है।

2- FollowSymlinks सक्षम करें

Options +FollowSymLinks 

वह एक, मुझे वास्तव में विवरण नहीं पता है, लेकिन मैंने इसे कई बार उल्लेख किया है, तो बस इसे करें।


निम्नलिखित उदाहरण के साथ समीकरण किया जा सकता है:

RewriteCond %{REQUEST_URI} ^/(server0|server1).*$ [NC]
# %1 is the string that was found above
# %1<>%{HTTP_COOKIE} concatenates first macht with mod_rewrite variable -> "test0<>foo=bar;"
#RewriteCond search for a (.*) in the second part -> \1 is a reference to (.*)
# <> is used as an string separator/indicator, can be replaced by any other character
RewriteCond %1<>%{HTTP_COOKIE} !^(.*)<>.*stickysession=\1.*$ [NC]
RewriteRule ^(.*)$ https://notmatch.domain.com/ [R=301,L]

गतिशील भार संतुलन:

यदि आप अपने सिस्टम को संतुलित करने के लिए mod_proxy का उपयोग करते हैं, तो वर्कर सर्वर की गतिशील रेंज जोड़ना संभव है।

RewriteCond %{HTTP_COOKIE} ^.*stickysession=route\.server([0-9]{1,2}).*$ [NC]
RewriteRule (.*) https://worker%1.internal.com/$1 [P,L]






mod-rewrite