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




.htaccess mod-rewrite (7)

रिवाइटबेस के साथ सौदा:

आपको लगभग हमेशा रिवाइटबेस सेट करने की आवश्यकता होती है। यदि आप नहीं करते हैं, तो apache अनुमान लगाता है कि आपका आधार आपकी निर्देशिका के लिए भौतिक डिस्क पथ है। तो इसके साथ शुरू करें:

RewriteBase /

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

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


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

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]

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

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

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

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

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

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

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


अन्य नुकसान:

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 

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


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 ) जो आपके अनुरोध को फिर से पारदर्शी नहीं करेगा।


mod_rewrite यूआरएल को बदलने के बिना अनुरोध हैंडलिंग के पहलुओं को संशोधित कर सकता है, उदाहरण के लिए पर्यावरण चर सेट करना, कुकीज़ सेट करना आदि। यह अविश्वसनीय रूप से उपयोगी है।

सशर्त रूप से एक पर्यावरण चर सेट करें:

RewriteCond %{HTTP_COOKIE} myCookie=(a|b) [NC]
RewriteRule .* - [E=MY_ENV_VAR:%b]

503 प्रतिक्रिया दें: RewriteRule का [R] ध्वज गैर-3xx मान ले सकता है और एक गैर-रीडायरेक्टिंग प्रतिक्रिया लौटा सकता है, उदाहरण के लिए प्रबंधित डाउनटाइम / रखरखाव के लिए:

RewriteRule .* - [R=503,L]

एक 503 प्रतिक्रिया लौटाएगा (प्रति रीडायरेक्ट नहीं)।

इसके अलावा, mod_rewrite mod_proxy पर एक सुपर-पावर इंटरफ़ेस की तरह कार्य कर सकता है, इसलिए आप ProxyPass निर्देश लिखने के बजाय ऐसा कर सकते हैं:

RewriteRule ^/(.*)$ balancer://cluster%{REQUEST_URI} [P,QSA,L]

राय: अनुरोध के लगभग किसी भी कल्पनीय पहलू के आधार पर विभिन्न अनुप्रयोगों या लोड बैलेंसर्स के अनुरोधों को रूट करने के लिए RewriteRule एस और RewriteCond एस का उपयोग करना बेहद शक्तिशाली है। बैकएंड के रास्ते पर अनुरोधों को नियंत्रित करना, और प्रतिक्रियाओं को उनके रास्ते पर संशोधित करने में सक्षम होना, सभी रूटिंग-संबंधित कॉन्फ़िगरेशन को केंद्रीकृत करने के लिए आदर्श स्थान mod_rewrite बनाता है।

इसे सीखने के लिए समय निकालें, यह इसके लायक है! :)


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

RewriteCond %{ENV:REDIRECT_STATUS} ^$

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







mod-rewrite