2012-02-07 16 views
21

के लिए nginx को पुनर्लेखन करना मैं को pushState-आधारित यूआरआई हैंडलिंग के साथ काम करने के लिए backbone.js जावास्क्रिप्ट ऐप में प्रबंधित करता हूं।पुशस्टेट-यूआरएल

अभी यूआरआई को एक स्तर के साथ एक्सेस करना, उदाहरण के लिए। example.com/users अच्छी तरह से काम करता है, लेकिन नहीं दो स्तर या गहरी यूआरआई के, इस तरह के रूप example.com/users/all, जो Backbone documentation में बताया गया है:

उदाहरण के लिए, आप के/दस्तावेज/100, अपने वेब सर्वर चाहिए एक मार्ग है, तो उस पृष्ठ की सेवा करने में सक्षम हो, तो ब्राउज़र का दौरा कि यूआरएल सीधे

तो, nginx के पुनर्लेखन के लिए विकल्पों के साथ परिचित से दूर किया जा रहा है, मैं अभी भी लगता है कि मैं rewrite^/index.html; की तरह कुछ कर सकते हैं मेरी index.html के लिए सब कुछ रीडायरेक्ट करने के लिए कर रहा हूँ , लेकिन loosi किसी भी अंतिम स्थैतिक फाइलों (छवियों, जावास्क्रिप्ट & सीएसएस) पर उसी आउट सर्वर पर संग्रहीत किया गया है जिसे मुझे एक्सेस करने में सक्षम होना चाहिए।

तो इस काम को करने के लिए नीचे दिखाए गए, वर्तमान कॉन्फ़िगरेशन के साथ मुझे क्या करना चाहिए?

server { 
    listen 80; 
    server_name example.com; 

    location/{ 
     root /var/www/example.com; 
     try_files $uri /index.html; 
    } 

} 

उत्तर

19

यहां मैंने अपने आवेदन के साथ क्या किया है। हर मार्ग (रूट यह स्वयं को छोड़कर) के साथ एक '/' न खत्म होने वाली index.html में काम करेगा:

Backbone.history.start({pushState: true, root: "/prefix/"}) 

और उसके बाद:

location ~ ^/prefix/ { 
    rewrite .* /index.html last; 
    } 

location ~ ^/.+/$ { 
    rewrite .* /index.html last; 
    } 

आप भी अपने मार्ग उपसर्ग कर सकते हैं या प्रत्येक मामले के लिए एक नियम परिभाषित करें।

#set root and index 
root /var/www/conferences/video/; 
index index.html; 

#route all requests that don't serve a file through index.html 
location/{ 
    if (!-e $request_filename){ 
     rewrite ^(.*)$ /index.html break; 
    } 
} 
+3

आपका पहला सुझाव स्लैश की आवश्यकता प्रतीत होता है ... फिर से लिखने के काम करता है जब मैं जाने के लिए "/ खोज /" लेकिन नहीं "/ search" – andrhamm

+1

यदि आपके पीछे पीछे की स्लैश नहीं है तो आप इसे कैसे हल करेंगे? –

+0

शायद एक regexp जो index.html के अलावा कुछ भी स्वीकार करता है? –

14

मैं इस तरह यह कामयाब ।

+1

मुझे इसका उपयोग करके 500 मिल गया। –

+0

यह कॉन्फ़िगरेशन मेरे लिए काम करता है! – llazzaro

30

मैं इस समाधान के साथ जा रहा समाप्त हो गया:

server { 

    listen 80; 
    server_name example.com; 
    root /var/www/example.com; 

    # Any route containing a file extension (e.g. /devicesfile.js) 
    location ~ ^.+\..+$ { 
     try_files $uri =404; 
    } 

    # Any route that doesn't have a file extension (e.g. /devices) 
    location/{ 
     try_files $uri /index.html; 
    } 

} 

इस तरह, कम से कम मैं अभी भी उचित 404 त्रुटियां मिलेंगी अगर एक फ़ाइल नहीं मिला है

+2

धन्यवाद, यह मेरे लिए काम किया। वास्तविक 404 होना महत्वपूर्ण है - यदि किसी जेएस फ़ाइल से अनुरोध किया गया है कि अस्तित्व में नहीं है और इसके बजाय HTML वापस लौटाया गया है, तो ब्राउज़र इसे जेएस के रूप में पार्स करने और सभी प्रकार की जेएस त्रुटियों को फेंकने का प्रयास करता है। वह एक एसपीए पेंच कर सकता है। – ccnokes

+1

यह उच्च होना चाहिए। फ़ाइलों के लिए सरल, सुरुचिपूर्ण, और 404 वास्तव में महत्वपूर्ण है – Igonato

7
ग्राहक के पक्ष एप्लिकेशन रास्तों के साथ

:

/ 
/foo 
/foo/bar 
/foo/bar/baz 
/foo/bar/baz/123 
/tacos 
/tacos/123 

उपयोग:

server { 
    listen 80; 
    server_name example.com; 
    root /var/www/example.com; 

    gzip_static on; 

    location/{ 
     try_files $uri $uri/ /index.html; 
    } 

    # Attempt to load static files, if not found route to @rootfiles 
    location ~ (.+)\.(html|json|txt|js|css|jpg|jpeg|gif|png|svg|ico|eot|otf|woff|woff2|ttf)$ { 
     try_files $uri @rootfiles; 
    } 

    # Check for app route "directories" in the request uri and strip "directories" 
    # from request, loading paths relative to root. 
    location @rootfiles { 
     rewrite ^/(?:foo/bar/baz|foo/bar|foo|tacos)/(.*) /$1 redirect; 
    } 
} 

रूट स्तर पर जड़ के लिए @Adam-Waite's answer काम करता है और पथ, स्थान संदर्भ में यदि का उपयोग कर एक antipattern माना जाता है , अपाचे शैली निर्देशों को परिवर्तित करते समय अक्सर देखा जाता है। देखें: http://wiki.nginx.org/IfIsEvil

अन्य उत्तरों प्रतिक्रिया-राउटर और एचटीएमएल 5 पुशस्टेट सक्षम का उपयोग कर एक समान प्रतिक्रिया ऐप में मेरे उपयोग मामले के लिए निर्देशिका गहराई के साथ मार्गों को कवर नहीं करते हैं। जब कोई मार्ग "निर्देशिका" जैसे example.com/foo/bar/baz/213123 के भीतर लोड या रीफ्रेश किया जाता है, तो मेरी index.html फ़ाइल किसी संबंधित पथ पर जेएस फ़ाइल का संदर्भ देगी और के बजाय example.com/foo/bar/baz/js/app.js को हल करेगी।

प्रथम स्तर जैसे /foo/bar/baz परे निर्देशिका गहराई के साथ मामलों के लिए, ध्यान दें निर्देशिका @rootfiles निर्देश में घोषित के आदेश: सबसे लंबे समय तक संभव पथ अगले उथले पथ /foo/bar और अंत में /foo के बाद, पहले जाने की जरूरत है।

0

चूंकि ajax अनुरोध एपीआई, इस मामले के लिए निम्नलिखित सूट हो सकता है,

server { 
    listen 80; 
    server_name example.com; 
    root /var/www/example.com; 

    # Any route containing a file extension (e.g. /devicesfile.js) 
    location ~ ^.+\..+$ { 
     try_files $uri =404; 
    } 

    # Any route that doesn't have a file extension (e.g. /devices) 
    location/{ 
     try_files $uri /index.html; 
    } 

    # The location block above provides the shortest prefix, of length one, 
    # and so only if all other location blocks fail to provide a match, 
    # this block will be used. 

    # Ajax api starts with /v1/ will be proxied 
    location /v1/ { 
     proxy_pass http://proxy; 
    } 
}