कोणीय 2/4/5 - गतिशील रूप से बेस href सेट करें


130

हमारे पास एक उद्यम ऐप है जो क्लाइंट के लिए कोणीय 2 का उपयोग करता है। हमारे प्रत्येक ग्राहक के अपने अलग-अलग url हैं, उदा: https://our.app.com/customer-oneऔर https://our.app.com/customer-two। वर्तमान में हम <base href...>गतिशील रूप से उपयोग करने में सक्षम हैं document.location। तो उपयोगकर्ता हिट https://our.app.com/customer-twoऔर सही <base href...>करने के लिए तैयार हो जाता है /customer-two...!

समस्या यह है कि यदि उपयोगकर्ता उदाहरण के लिए है https://our.app.com/customer-two/another-pageऔर वे पृष्ठ को ताज़ा करते हैं या उस url को सीधे हिट करने का प्रयास करते हैं, तो <base href...>सेट हो जाता है /customer-two/another-pageऔर संसाधन नहीं मिल सकते हैं।

हमने बिना किसी लाभ के निम्नलिखित कोशिश की है:

<!doctype html>
<html>

<head>
  <script type='text/javascript'>
    var base = document.location.pathname.split('/')[1];
    document.write('<base href="https://stackoverflow.com/' + base + '" />');
  </script>

...

दुर्भाग्य से हम विचारों से बाहर हैं। कोई भी मदद आश्चर्यजनक होगी।


1
क्या आपने APP_BASE_HREF के साथ कुछ भी करने का प्रयास किया है ? मुझे पूरा यकीन नहीं है कि इसे कैसे लागू किया जाएगा, लेकिन ऐसा लगता है कि यह उपयोगी होगा ...
जारोद मोजर

बेशक यह निश्चित रूप से निर्भर करता है कि आप वर्तमान में राउटर के किस संस्करण का उपयोग कर रहे हैं। क्या आप राउटर संस्करण 3.0.0-alpha.x पर हैं?
जैरोड मोजर

मैं "@ कोणीय / राउटर" का उपयोग कर रहा हूं: "3.0.0-alp.7"
3

5
कोणीय 7 - नवंबर 2018. यह अभी भी एक मुद्दा है। वर्तमान उत्तर आंशिक समाधान प्रदान करते हैं। कोणीय मॉड्यूल के अंदर सामान करना बहुत देर हो चुकी है। जैसा कि आपके सूचकांक HTML को परोसा जाता है, यह जानना आवश्यक है कि स्क्रिप्ट को कहां से खींचना है। जिस तरह से मैं इसे देख रहा हूँ केवल 2 तरीके हैं - गतिशील बेसहेर सामग्री के साथ index.html की सेवा करने के लिए जो कुछ भी है उसका उपयोग कर रहे हैं। या मूल सामग्री को जावास्क्रिप्ट से सही उपयोग करते हुए index.html फ़ाइल को कोणीय में लाने से पहले DOM सामग्री को बदलने के लिए। दोनों एक आम समस्या के खराब समाधान हैं। दुखी।
स्टैव्म

1
क्या कोई कृपया मेरे प्रश्न का उत्तर दे सकता है। stackoverflow.com/questions/53757931/…
करण

जवाबों:


166

यहाँ चिह्नित उत्तर ने मेरे मुद्दे को हल नहीं किया, संभवतः विभिन्न कोणीय संस्करण। मैं angular cliटर्मिनल / शेल में निम्नलिखित कमांड के साथ वांछित परिणाम प्राप्त करने में सक्षम था :

ng build --base-href /myUrl/

ng build --bh /myUrl/ या ng build --prod --bh /myUrl/

यह बदलता है <base href="https://stackoverflow.com/">करने के लिए <base href="https://stackoverflow.com/myUrl/">में बनाया संस्करण केवल जो विकास और उत्पादन के बीच वातावरण में हमारे परिवर्तन के लिए एकदम सही था। सबसे अच्छा हिस्सा कोई कोड आधार नहीं था जिसे इस पद्धति का उपयोग करके बदलना आवश्यक है।


संक्षेप में, अपने index.htmlआधार को इस प्रकार छोड़ें : <base href="https://stackoverflow.com/">फिर ng build --bh ./इसे एक सापेक्ष पथ बनाने के लिए कोणीय cli के साथ चलाएं , या ./जो कुछ भी आवश्यक हो उसे प्रतिस्थापित करें ।


अपडेट करें:

जैसा कि ऊपर दिए गए उदाहरण से पता चलता है कि इसे कमांड लाइन से कैसे किया जाता है, यहां बताया गया है कि इसे अपनी कोणीय.जॉन कॉन्फ़िगरेशन फ़ाइल में कैसे जोड़ा जाए।

यह सभी ng servingस्थानीय विकास के लिए उपयोग किया जाएगा

"architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
      "options": {
        "baseHref": "/testurl/",

यह विन्यास के लिए विशिष्ट विन्यास है जो ठेस जैसी है:

"configurations": {
   "Prod": {
     "fileReplacements": [
        {
          "replace": src/environments/environment.ts",
          "with": src/environments/environment.prod.ts"
        }
      ],
      "baseHref": "./productionurl/",

आधिकारिक angular-cli प्रलेखन उपयोग का जिक्र है।


35
इस समाधान के लिए प्रति ग्राहक एक निर्माण की आवश्यकता होती है, जो संभवतः ओपी की समस्या को हल नहीं कर रहा है।
मैक्सिम मोरिन

1
@MaximeMorin मेरे अनुभव में अब तक ऐसा करना, ./सभी स्थानों के लिए काम करता है। इसलिए वास्तव में मुझे नहीं लगता कि आपको प्रति ग्राहक का निर्माण करना होगा।
ज़ेज़

9
@Zze के साथ मेरा अनुभव ./बहुत अलग रहा है। यह तब तक काम करता है जब तक उपयोगकर्ता एक मार्ग पर नेविगेट नहीं करता है और ब्राउज़र के ताज़ा बटन या कुंजियों को हिट करता है। उस बिंदु पर, हमारे पुनर्लेखन कॉल को संभालते हैं, इंडेक्स पेज पर कार्य करते हैं, लेकिन ब्राउज़र मानता है कि ./वर्तमान मार्ग वेब ऐप का रूट फ़ोल्डर नहीं है। हमने ओपी के मुद्दे को एक डायनेमिक (.aspx, .php, .jsp, आदि) इंडेक्स के साथ हल किया है जो बेस href सेट करता है।
मैक्सिम मोरीन

2
--prodबिल्ड के दौरान उपयोग करने से आपका base hrefमूल्य नहीं बदलेगा , आपको यहां इसके बारे में बात नहीं करनी चाहिए। --prodबताता है angular-cliका उपयोग करने के environment.prod.tsबजाय फ़ाइल डिफ़ॉल्ट फ़ाइल का environment.tsअपने में environmentsफ़ोल्डर
Mattew अनंत काल

1
@MattewEon यह दर्शाता है कि --prodओपी में तैनाती की बात करने के बाद से यह ध्वज के साथ संगत था ।
बजे

57

यहाँ हमने क्या करना समाप्त किया।

इसे index.html में जोड़ें। यह <head>अनुभाग में पहली चीज होनी चाहिए

<base href="https://stackoverflow.com/">
<script>
  (function() {
    window['_app_base'] = '/' + window.location.pathname.split('/')[1];
  })();
</script>

फिर app.module.tsफ़ाइल में, { provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' }प्रदाताओं की सूची में जोड़ें , जैसे:

import { NgModule, enableProdMode, provide } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { APP_BASE_HREF, Location } from '@angular/common';


import { AppComponent, routing, appRoutingProviders, environment } from './';

if (environment.production) {
  enableProdMode();
}

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    HttpModule,
    routing],
  bootstrap: [AppComponent],
  providers: [
    appRoutingProviders,
    { provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' },
  ]
})
export class AppModule { }

त्रुटि TS7017: तत्व का स्पष्ट रूप से एक 'कोई' प्रकार है क्योंकि टाइप 'विंडो' में कोई इंडेक्स हस्ताक्षर नहीं है। useValue: (window as any) ['_app_base'] || '/'मदद करता है
एरकन बुलबुएल

वास्तव में नवीनतम ng2 के लिए काम नहीं करता है, क्या कोई समाधान है? (खराब स्क्रिप्ट पथ को लोड करता है, फिर अच्छी स्क्रिप्ट पथ, लेकिन मोबाइल पर नहीं)
अमित

1
नीचे दिए गए उत्तर के रूप में इसे जोड़ना, क्योंकि टिप्पणी के लिए सामग्री की लंबाई बहुत लंबी है।
कृष्णन

1
@Amit कृपया नवीनतम ng2 में एक आसान समाधान के लिए मेरा जवाब नीचे देखें।
21

3
आपने अन्य फ़ाइलों के साथ समस्या को कैसे हल किया। मेरा ब्राउज़र लोकलहोस्ट को लोड करने की कोशिश कर रहा है : 8080 / main.bundle.js , लेकिन यह नहीं हो सकता क्योंकि मेरा संदर्भ अलग है? (यह प्राप्त कर रहा है होना चाहिए स्थानीय होस्ट: 8080 / हैलो / main.bundle.js। )
ससा

33

आपके (@Sharpmachine) उत्तर के आधार पर, मैं इसे थोड़ा और सुधारने में सक्षम था, ताकि हमें किसी फ़ंक्शन को हैक न करना पड़े index.html

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { APP_BASE_HREF, Location } from '@angular/common';

import { AppComponent } from './';
import { getBaseLocation } from './shared/common-functions.util';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    HttpModule,
  ],
  bootstrap: [AppComponent],
  providers: [
    appRoutingProviders,
    {
        provide: APP_BASE_HREF,
        useFactory: getBaseLocation
    },
  ]
})
export class AppModule { }

और, ./shared/common-functions.util.tsइसमें शामिल हैं:

export function getBaseLocation() {
    let paths: string[] = location.pathname.split('/').splice(1, 1);
    let basePath: string = (paths && paths[0]) || 'my-account'; // Default: my-account
    return '/' + basePath;
}

1
मेरे पास myf सबफ़ोल्डर में तैनात है। मेरा url अब इस तरह दिखता है: http://localhost:8080/subfolder/myapp/#/subfolder/myrouteक्या यह तुम्हारा कैसा दिखता है? क्या आप जानते हैं कि # के बाद सबफ़ोल्डर से छुटकारा कैसे प्राप्त करें ताकि यह बस हो सके http://localhost:8080/subfolder/myapp/#/myroute?
techguy2000

ओह। मुझे लगता है कि Href बेस केवल LocationStrategy के लिए आवश्यक है। मेरे मामले में, मैं HashLocationStrategy का उपयोग कर रहा हूं। तो मैं भी इसे सेट करने की जरूरत नहीं है। क्या आपने LocationStrategy के साथ रिफ्रेश को हैंडल करने के लिए विशेष कोड लिखा है?
Techguy2000 19

1
हां, base hrefकेवल LocationStrategyAFAIK के लिए आवश्यक है । LocationStrategy के साथ रिफ्रेश को हैंडल करने के लिए विशेष कोड लिखने के लिए, निश्चित रूप से नहीं कि आप वास्तव में क्या मतलब है। क्या आप पूछ रहे हैं, अगर मेरे ऐप में किसी गतिविधि के दौरान मेरा "बेस href" बदल जाए तो क्या होगा? फिर, हां, मुझे एक गंदा काम करना पड़ा, window.location.href = '/' + newBaseHref;जहां इसे बदलना आवश्यक था। मुझे इस पर बहुत गर्व नहीं है। इसके अलावा, एक अद्यतन देने के लिए, मैं अपने ऐप में इन हैक समाधानों से दूर चला गया क्योंकि यह मेरे लिए एक डिजाइन समस्या बन रहा था। राउटर परम पूरी तरह से ठीक काम करते हैं, इसलिए मैं इसे करने के लिए अटक गया।
कृष्णन

1
आपका क्या appRoutingProviderदिखता है, कृष्णन? मैं उसी के उपयोग किए गए स्वीकृत उत्तर देखता हूं; हो सकता है कि आपने अभी उसकी नकल की हो providers, लेकिन यदि नहीं, तो आप मुझे एक नमूना दे सकते हैं या उसका उद्देश्य बता सकते हैं? प्रलेखन केवल importsमॉड्यूल मार्ग , यह किसी भी मार्ग से संबंधित प्रदाताओं (जहाँ तक मैं देख सकते हैं) का उपयोग नहीं करता
लाल मटर

@ कृष्णन यह काम करने के लिए मुझे नग्नेक्स के साथ क्या करना है:location /subfolder/myapp/ { try_files $uri /subfolder/myapp/index.html; } location /subfolder2/myapp/ { try_files $uri /subfolder2/myapp/index.html; }
techguy2000

24

मैं ./एक ही डोमेन से कई ऐप बनाते समय वर्तमान वर्किंग डायरेक्टरी का उपयोग करता हूं :

<base href="./">

एक साइड नोट पर, मैं .htaccessपेज रिलोड पर अपनी रूटिंग के साथ सहायता करने के लिए उपयोग करता हूं:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.html [L]

2
.htaccessफाइल के लिए बहुत बहुत धन्यवाद
शाहरियार सिराज स्निग्धो

8
यह उत्तर गलत है, यह ऐसे मार्गों के लिए काम नहीं करता है जैसे / आपका-ऐप / ए / बी / सी। यदि आप अपने पृष्ठ को ऐसे मार्ग से ताज़ा करते हैं, तो कोणीय आपके / app / a / b / के तहत रनटाइम, पॉलीफ़िल और मुख्य JS फाइल और स्टाइल CSS फ़ाइल को खोजेगा। वे स्पष्ट रूप से उस स्थान पर नहीं हैं, लेकिन के तहत / अपने-ऐप /
toongeorges

2
@toongeorges यह उत्तर लगभग दो साल पहले एक कॉन्फ़िगरेशन फ़ाइल का उपयोग करके लिखा गया था जो पेज रीलोड पर रूटिंग को संभालने के लिए अपाचे वेब सर्वर सॉफ्टवेयर द्वारा पता लगाया और निष्पादित किया गया है। आपके लिए यह कहना गलत है कि यह समाधान गलत नहीं है और काम भ्रामक नहीं है, लेकिन आपके कहने का मतलब यह है कि आप यह नहीं पता लगा सकते हैं कि इसे अपने कॉन्फ़िगरेशन के साथ कैसे काम करें।
डायरिक

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

2
नाह, @toongeorges सही है, बदलना <base href="./">गलत है और /app/a/b/cवास्तव में जैसे मार्गों के साथ बकवास करेगा , बस इसका परीक्षण किया। यदि आप केवल वेब ऐप के साथ काम कर रहे हैं या तैनाती के आधार बेस को बदलने के कोणीय तरीके पर एक नज़र डालते हैं (तो इस बात का उल्लेख यहां बहुत सारे उत्तर हैं)।
giovannipds

15

@Sharpmachine द्वारा मौजूदा उत्तर का सरलीकरण ।

import { APP_BASE_HREF } from '@angular/common';
import { NgModule } from '@angular/core';

@NgModule({
    providers: [
        {
            provide: APP_BASE_HREF,
            useValue: '/' + (window.location.pathname.split('/')[1] || '')
        }
    ]
})

export class AppModule { }

यदि आप APP_BASE_HREF अपारदर्शी टोकन के लिए मान प्रदान कर रहे हैं, तो आपको अपने index.html में आधार टैग निर्दिष्ट करने की आवश्यकता नहीं है।


10

यह मेरे लिए ठीक ठाक माहौल में काम करता है

<base href="https://stackoverflow.com/" id="baseHref">
<script>
  (function() {
    document.getElementById('baseHref').href = '/' + window.location.pathname.split('/')[1] + "/";
  })();
</script>

2
इस समाधान में IIS में कई VD सेटअप के साथ एक महान सीमा है। यह चंक्स की डुप्लिकेट लोडिंग का कारण बनता है।
करण

9

कोणीय 4 में, आप आधारहेयर को .angular-cli.json ऐप्स में भी कॉन्फ़िगर कर सकते हैं।

, .कुलर-क्लि.जसन

{   ....
 "apps": [
        {
            "name": "myapp1"
            "baseHref" : "MY_APP_BASE_HREF_1"
         },
        {
            "name": "myapp2"
            "baseHref" : "MY_APP_BASE_HREF_2"
         },
    ],
}

यह index.html में MY_APP_BASE_HREF_1 पर बेस href अपडेट करेगा

ng build --app myapp1

4
इसके लिए प्रत्येक ऐप के लिए एक बिल्ड बनाने की भी आवश्यकता है।
पैट्रिक हिलर्ट

6

यदि आप कोणीय सीएलआई 6 का उपयोग कर रहे हैं, तो आप angular.json (प्रोजेक्ट्स> xxx> आर्किटेक्ट> बिल्ड> कॉन्फ़िगरेशन> प्रोडक्शन) में तैनाती / आधार विकल्प का उपयोग कर सकते हैं। इस तरह, आप आसानी से बेस प्रोजेक्ट प्रति प्रोजेक्ट निर्दिष्ट कर सकते हैं।

चेक करें कि आपकी सेटिंग्स बिल्ट ऐप के index.html को देखकर सही हैं।


7
इसके प्रत्येक वातावरण के लिए इसके सभी निहितार्थों के साथ एक अलग निर्माण की आवश्यकता होती है।
रात्रि .

3

ऐड-ऑन: यदि आप उदाहरण के लिए चाहते हैं: / राउटर के लिए आवेदन आधार के रूप में / और संपत्ति के उपयोग के लिए आधार के रूप में जनता

$ ng build -prod --base-href /users --deploy-url /public

1

इसी तरह की समस्या थी, वास्तव में मैं अपने वेब के भीतर कुछ फ़ाइल के अस्तित्व की जांच करने में समाप्त हो गया।

जांचपाठ उस फ़ाइल का सापेक्ष URL होगा जिसे आप चेक करना चाहते हैं (यदि आप सही स्थान पर हैं, तो एक मार्कर की तरह), जैसे कि 'संपत्ति / चित्र / thisImageAlwaysExists.png'

<script type='text/javascript'>
  function configExists(url) {
    var req = new XMLHttpRequest();
    req.open('GET', url, false); 
    req.send();
    return req.status==200;
  }

  var probePath = '...(some file that must exist)...';
  var origin = document.location.origin;
  var pathSegments = document.location.pathname.split('/');

  var basePath = '/'
  var configFound = false;
  for (var i = 0; i < pathSegments.length; i++) {
    var segment = pathSegments[i];
    if (segment.length > 0) {
      basePath = basePath + segment + '/';
    }
    var fullPath = origin + basePath + probePath;
    configFound = configExists(fullPath);
    if (configFound) {
      break;
    }
  }

  document.write("<base href='" + (configFound ? basePath : '/') + "' />");
</script>

-1

सच कहूं, तो आपका मामला मेरे लिए ठीक काम करता है!

मैं कोणीय 5 का उपयोग कर रहा हूं।

<script type='text/javascript'>
    var base = window.location.href.substring(0, window.location.href.toLowerCase().indexOf('index.aspx'))
    document.write('<base href="' + base + '" />');
</script>

क्या यह समाधान आपके लिए काम करता है? मैं समस्या का सामना कर रहा हूं। क्या आप कृपया मेरी पोस्ट का जवाब दे सकते हैं। stackoverflow.com/questions/53757931/…
करण

1
कृपया दस्तावेज का उपयोग करने से बचें। (): Developers.google.com/web/updates/2016/08/…
पैट्रिक हिलर्ट

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.