एचटीएमएल 5 और हैशबैंग मोड / लिंक पुनर्लेखन के बीच $ स्थान / स्विचिंग


179

मैं इस धारणा के तहत था कि कोणीय, टेम्प्लेट के भीतर एंकर टैग के हाइपर विशेषताओं में दिखाई देने वाले URL को फिर से लिखेंगे, जैसे कि वे html5 मोड या हैशबैंग मोड में काम करेंगे। स्थान सेवा के लिए दस्तावेज़ीकरण यह कहता प्रतीत होता है कि HTML लिंक पुनर्लेखन हैशबंग स्थिति का ध्यान रखता है। मैं इस प्रकार अपेक्षा करूंगा कि जब HTML5 मोड में नहीं, हैश डाला जाएगा, और HTML5 मोड में, वे नहीं करेंगे।

हालांकि, ऐसा लगता है कि कोई पुनर्लेखन नहीं हो रहा है। निम्न उदाहरण मुझे केवल मोड बदलने की अनुमति नहीं देता है। आवेदन में सभी लिंक को हाथ से फिर से लिखना होगा (या रनटाइम पर एक चर से व्युत्पन्न होगा। क्या मुझे मोड के आधार पर सभी URL को मैन्युअल रूप से लिखना होगा?

मुझे कोणीय 1.0.6, 1.1.4 या 1.1.3 में चल रहे किसी भी क्लाइंट-साइड url के पुनर्लेखन की जानकारी नहीं है। ऐसा लगता है कि सभी href मानों को # हैशबैंग मोड के लिए और / html5 मोड के लिए तैयार करने की आवश्यकता है।

क्या पुनर्लेखन का कारण कुछ विन्यास आवश्यक है? क्या मैं डॉक्स को गलत बता रहा हूं? कुछ और मूर्खतापूर्ण कर रहे हो?

यहाँ एक छोटा सा उदाहरण दिया गया है:

<head>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.3/angular.js"></script>
</head>

<body>
    <div ng-view></div>
    <script>
        angular.module('sample', [])
            .config(
        ['$routeProvider', '$locationProvider',
            function ($routeProvider, $locationProvider) {

                //commenting out this line (switching to hashbang mode) breaks the app
                //-- unless # is added to the templates
                $locationProvider.html5Mode(true);

                $routeProvider.when('/', {
                    template: 'this is home. go to <a href="https://stackoverflow.com/about"/>about</a>'
                });
                $routeProvider.when('/about', {
                    template: 'this is about. go to <a href="https://stackoverflow.com/"/>home</a'
                });
            }
        ])
            .run();
    </script>
</body>

परिशिष्ट: मेरे प्रश्न को फिर से पढ़ते हुए, मैं देखता हूं कि मैंने "पुनर्लेखन" शब्द का उपयोग स्पष्टता की प्रचुरता के बिना किया कि मैं कौन और कब लिखना चाहता था। सवाल यह है कि URL को फिर से लिखने के लिए कोणीय को कैसे प्राप्त किया जाए , जब यह पथ प्रदान करता है और दो मोड में समान रूप से JS कोड में पथ की व्याख्या करने के लिए इसे कैसे प्राप्त करें। यह अनुरोधों के HTML5- संगत पुनर्लेखन करने के लिए एक वेब सर्वर को कैसे पैदा करना है , इसके बारे में नहीं है


1
यहाँ है समाधान के लिए कोणीय 1.6
मिस्टालिस

जवाबों:


361

AngularJS रूटिंग के बारे में प्रलेखन बहुत स्पष्ट नहीं है। यह हैशबैंग और एचटीएमएल 5 मोड के बारे में बात करता है। वास्तव में, AngularJS रूटिंग तीन मोड में संचालित होती है:

  • हैशबैंग मोड
  • HTML5 मोड
  • एचटीएमएल 5 मोड में हैशबैंग

प्रत्येक मोड के लिए एक संबंधित स्थान है

URL पुनर्लेखन को अनुकरण करने के लिए आपको वास्तव में html5mode को सही और $ sniffer वर्ग को सजाने के लिए निम्नानुसार सेट करना होगा:

$provide.decorator('$sniffer', function($delegate) {
  $delegate.history = false;
  return $delegate;
});

अब मैं इसे और अधिक विस्तार से समझाऊंगा:

हैशबैंग मोड

विन्यास:

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
});
$locationProvider
  .html5Mode(false)
  .hashPrefix('!');

यह वह स्थिति है जब आपको अपने HTML फ़ाइलों में हैश के साथ URL का उपयोग करने की आवश्यकता होती है जैसे कि

<a href="index.html#!/path">link</a>

ब्राउज़र में आपको निम्न लिंक का उपयोग करना चाहिए: http://www.example.com/base/index.html#!/base/path

जैसा कि आप शुद्ध हैशबैंग मोड में देख सकते हैं कि HTML फ़ाइलों में सभी लिंक आधार के साथ शुरू होने चाहिए जैसे कि "index.html #!"।

HTML5 मोड

विन्यास:

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true);

आपको आधार को HTML- फाइल में सेट करना चाहिए

<html>
  <head>
    <base href="/">
  </head>
</html>

इस मोड में आप HTML फ़ाइलों में # बिना लिंक का उपयोग कर सकते हैं

<a href="/path">link</a>

ब्राउज़र में लिंक:

http://www.example.com/base/path

एचटीएमएल 5 मोड में हैशबैंग

यह मोड तब सक्रिय होता है जब हम वास्तव में एचटीएमएल 5 मोड का उपयोग करते हैं लेकिन असंगत ब्राउज़र में। हम $ sniffer सेवा को सजाने और झूठे इतिहास को स्थापित करके इस मोड को एक संगत ब्राउज़र में अनुकरण कर सकते हैं।

विन्यास:

$provide.decorator('$sniffer', function($delegate) {
  $delegate.history = false;
  return $delegate;
});
$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true)
  .hashPrefix('!');

आधार को HTML- फाइल में सेट करें:

<html>
  <head>
    <base href="/">
  </head>
</html>

इस मामले में लिंक को HTML फ़ाइल में हैश के बिना भी लिखा जा सकता है

<a href="/path">link</a>

ब्राउज़र में लिंक:

http://www.example.com/index.html#!/base/path

विस्तृत विवरण, @jupiter के लिए धन्यवाद। मैं देखूंगा कि क्या मैं बैंग को छोड़ सकता हूं और मोड के आधार पर URL के दो सेट की आवश्यकता नहीं होने पर हैश और ट्रिक कोणीय रख सकता हूं!
लॉरेलनाईड

1
मुझे लगता है कि मैंने आपकी समस्या को ठीक से नहीं समझा है। आप बिना हैश के सिर्फ URL का उपयोग क्यों नहीं करते? वे इतिहास API का समर्थन करने वाले ब्राउज़र में काम करेंगे और ब्राउज़र API का समर्थन नहीं करेंगे। AngularJS # संस्करण को उस स्थान बार में डाल देगा जब आप उन ब्राउज़र पर क्लिक करते हैं जो इतिहास API का समर्थन नहीं करते हैं क्योंकि AngularJS लिंक पर क्लिक स्वीकार करता है।
बृहस्पति

मैं एक ऐसे ढांचे पर काम कर रहा हूं, जिसमें दोनों तरीकों का समर्थन होना चाहिए। ऐप लेखकों को इस बात की चिंता किए बिना एक या दूसरे को चुनने में सक्षम होना चाहिए कि उनके टेम्प्लेट में हैश हैं या नहीं और / या रिश्तेदार रास्तों की व्याख्या में बदलाव हैं। मुझे उम्मीद है कि आपकी ट्रिक यह सच करने में मदद करेगी कि "आप जो कुछ भी करते हैं वह मोड बदल रहा है" (भले ही व्यावहारिक समाधान "एचटीएमएल 5 के लिए मोड सेट करें और फिर ब्राउज़र क्षमताओं के बारे में कोणीय में झूठ हो)"।
लॉरेलनाईड

1
मैं $provideअपरिभाषित हो रहा हूँ ?
पेट्रस थेरॉन

1
@pate - जब आप डेकोरेटर की स्थापना कर रहे हों, तब आपको अपने कॉन्फिगर फंक्शन में $ इंजेक्शन लगाने की आवश्यकता होती है।
लॉरेलनाईड

8

फर भविष्य के पाठकों, अगर आप कोणीय 1.6 का उपयोग कर रहे हैं, तो आपको भी बदलना होगा hashPrefix:

appModule.config(['$locationProvider', function($locationProvider) {
    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix('');
}]);

अपने HTML में आधार सेट करना न भूलें <head>:

<head>
    <base href="/">
    ...
</head>

चैंज के बारे में अधिक जानकारी here


3
धन्यवाद @ मिस्टालिस आपका जवाब काम ठीक है। लेकिन जब मैं रूट करने के बाद पेज को रिफ्रेश करता हूं, तो पेज नहीं मिलता है। कृपया मेरी मदद करें ..
आशीष मेहता

@ आशीषमेहा नमस्ते आशीष मेरा सुझाव है कि आप इस उत्तर को पढ़ें , इससे आपकी समस्या का समाधान हो सकता है। अलविदा! :)
मिस्टालिस

0

मुझे यह पता लगाने में थोड़ा समय लगा कि इस तरह से मुझे यह काम कर रहा है - Angular WebAPI ASP रूटिंग बिना #

  1. index.html - base href = "/"> में जोड़ें
  2. $ स्थान जोड़ें Provider.html5Mode (सच); app.config के लिए

  3. मुझे छवियों को अपलोड करने के लिए एक निश्चित नियंत्रक (जो होम कंट्रोलर में था) की आवश्यकता थी, इसलिए मैंने रूटकॉन्फिग में उस नियम को जोड़ा

         routes.MapRoute(
            name: "Default2",
            url: "Home/{*.}",
            defaults: new { controller = "Home", action = "SaveImage" }
        );
  4. Global.asax में निम्नलिखित जोड़ें - एपीआई और छवि अपलोड पथों को अनदेखा करने के लिए सुनिश्चित करें कि उन्हें सामान्य रूप से कार्य करने दें अन्यथा सब कुछ फिर से करें।

     private const string ROOT_DOCUMENT = "/Index.html";
    
    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        var path = Request.Url.AbsolutePath;
        var isApi = path.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase);
        var isImageUpload = path.StartsWith("/home", StringComparison.InvariantCultureIgnoreCase);
    
        if (isApi || isImageUpload)
            return;
    
        string url = Request.Url.LocalPath;
        if (!System.IO.File.Exists(Context.Server.MapPath(url)))
            Context.RewritePath(ROOT_DOCUMENT);
    }
  5. $ Location.url ('/ XXX') का उपयोग करना सुनिश्चित करें और पुनर्निर्देशित करने के लिए window.location ... का उपयोग न करें

  6. CSS फाइलों को निरपेक्ष पथ के साथ संदर्भ दें

और नहीं

<link href="app/content/bootstrapwc.css" rel="stylesheet" />

अंतिम नोट - इस तरह से करने से मुझे पूरा नियंत्रण मिल गया और मुझे वेब कॉन्फ़िगरेशन के लिए कुछ भी करने की आवश्यकता नहीं थी।

आशा है कि यह मदद करता है क्योंकि यह मुझे पता लगाने के लिए कुछ समय लगा।


0

मैं अपने एप्लिकेशन को HTML5 मोड और एक निश्चित टोकन के साथ एक्सेस करने में सक्षम होना चाहता था और फिर हैशबैंग विधि (टोकन रखने के लिए ताकि उपयोगकर्ता अपने पृष्ठ को ताज़ा कर सके) पर स्विच कर सके।

मेरा ऐप एक्सेस करने के लिए URL:

http://myapp.com/amazing_url?token=super_token

तब जब उपयोगकर्ता पृष्ठ लोड करता है:

http://myapp.com/amazing_url?token=super_token#/amazing_url

तब जब उपयोगकर्ता नेविगेट करता है:

http://myapp.com/amazing_url?token=super_token#/another_url

इसके साथ मैं URL में टोकन रखता हूं और जब उपयोगकर्ता ब्राउज़ कर रहा होता है तो राज्य रखता है। मैंने URL की थोड़ी दृश्यता खो दी है, लेकिन इसे करने का कोई सही तरीका नहीं है।

तो HTML5 मोड को सक्षम न करें और फिर इस नियंत्रक को जोड़ें:

.config ($stateProvider)->
    $stateProvider.state('home-loading', {
         url: '/',
         controller: 'homeController'
    })
.controller 'homeController', ($state, $location)->
    if window.location.pathname != '/'
        $location.url(window.location.pathname+window.location.search).replace()
    else
        $state.go('home', {}, { location: 'replace' })
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.