web-dev-qa-db-fra.com

URL relative dans JQuery Post Call

J'ai la situation suivante.

J'ai développé ma première application MVC Asp.Net. il fonctionne sur mon serveur à l'adresse suivante

http://localhost:59441/

J'ai écrit quelques méthodes de publication JQuery qui ressemblaient à ceci

  $.ajax({
        type: "POST",
        url: "/CeduleGlobale/UpdateCheckBox", ...

CeduleGlobale est mon ControllerName Et UpdateCheckBox est mon methodName

Lorsque je mets l’application sur le serveur de test, elle est placée dans un répertoire virtuel.

donc l'application est maintenant

http://testServer/JprApplication/

plus de port à spécifier et aussi un nom d'application

Lorsque j'ai commencé à tester, j'ai rapidement remarqué que mes appels JQuery Post ne fonctionnaient plus ...

Je les ai modifiées alors maintenant l'URL est

/JprMvc/CeduleGlobale/UpdateCheckBox

le problème est 2 fois. 

  1. cela rend difficile le test sur ma machine de développement car IIS Express ne me permet pas de spécifier un répertoire virtuel.
  2. Je n'aime pas le codage en dur du nom de répertoire virtuel dans JQuery, car je ne sais pas quel nom l'application aura dans l'environnement de production et je devrai donc modifier mon script avant de pouvoir installer l'application en production.

Je suis sûr qu'il me manque quelque chose de base pour simplifier cela.

Merci

22
SerenityNow

En fonction de l'emplacement réel de votre JavaScript (dans la vue ou dans un fichier JS séparé), vous disposez de plusieurs options.

Option 1 - Dans la vue

Utilisez simplement les aides HTML pour générer les liens pour vous

<script type="text/javascript">
   $(function(){
        $.ajax({
           type: "POST",
           url: "@Url.Action("UpdateCheckBox", "CeduleGlobale")"
        });
   });
</script>

Option 2 - Fichier JS autonome

Nous avons généralement une fonction par page qui configure les gestionnaires de cette page. Donc, nous pouvons faire quelque chose comme ceci:

Vue

<script type="text/javascript">
    $(function(){
        SetOrderPage('@Url.Action("UpdateCheckBox", "CeduleGlobale")');
    });
</script>

Fichier JS autonome

function SetOrderPage(ajaxPostUrl){
       $.ajax({
           type: "POST",
           url: ajaxPostUrl
       )};
}

Option 3 - Fichier JS autonome, méthode 2

Vous pourriez avoir une variable globale dans votre fichier JS qui est le siteroot. L'inconvénient ici est que vous devrez créer manuellement chacun de vos chemins de méthode d'action. Sur chaque page, vous pouvez définir la variable globale racine du site en tant que telle:

Fichier JS autonome

var siteRoot;

Vue

<script type="text/javascript">
    siteRoot = '@Request.ApplicationPath';
</script>

N'oubliez pas que vous ne pouvez pas utiliser la syntaxe Razor dans un fichier JS autonome. Je pense qu'il est préférable de laisser Razor/MVC/.NET vous donner de manière dynamique le chemin du site ou l'URL, car cela réduira réellement les erreurs pouvant être commises lors du déplacement entre les sites/répertoires virtuels.

42
Tommy

Autant que je sache, il n'y a pas d'autre moyen de contourner cela. À moins que vous ne souhaitiez utiliser des URL relatives I.e:

$.ajax({
        type: "POST",
        url: "./CeduleGlobale/UpdateCheckBox", ...

Mais cela peut devenir compliqué pour différentes raisons lorsque vous refactorisez le code . Vous pouvez également préfixer l'URL définie de manière globale et, par conséquent, il vous suffit de la modifier une seule fois avant de passer en production.

c'est à dire.

//Globally defined serverRoot
serverRoot = "http://someaddress/somevirtualdirectory";

$.ajax({
        type: "POST",
        url: serverRoot + "/CeduleGlobale/UpdateCheckBox", ...

De cette façon, si vous n'en avez pas besoin, vous pouvez simplement définir serverRoot = ''; et tout sera comme avant.

7
Rob Schmuecker

JQuery avait ce problème avec MVC 5, alors je suis allé à cette solution qui élimine le problème lorsque vous êtes dans Localhost et dans n’importe quel navigateur même lorsque vous déployez une application dans un sous-dossier.

var pathname = window.location.pathname;
var VirtualDirectory;
if (pathname.indexOf("localhost") >= 0 && pathname.indexOf(":") >= 0) {
    VirtualDirectory = "";
}
else {
    if ((pathname.lastIndexOf('/')) === pathname.length + 1) {
        VirtualDirectory = pathname.substring(pathname.indexOf('/'), pathname.lastIndexOf('/'));
    } else {
        VirtualDirectory = pathname;
    }
}

Et puis dans tout appel ajax:

$.post(VirtualDirectory + "/Controller/Action", { data: data}, "html")
             .done(function (result) {
                 //some code             
});
2
RizzCandy

Passez @ Url.Action ("action", "contrôleur") au javascript de la vue. Cela lui permettra d'être mis à jour de manière dynamique au moment de l'exécution.

<script>
   myJavascriptfunction(@Url.Action("action","controller"),param1,param2);
</script>

Il peut y avoir une fonction pour obtenir le chemin racine également que vous pourriez utiliser pour initialiser les variables racine dans les réponses précédentes.

1
Codersjunto

Je sais que c'est un ancien post. Mais j'avais le même problème et je me suis retrouvé ici. Et réussi à résoudre ce problème avec UrlHelper.Action méthode. Il devrait être utilisé quelque chose comme ceci. (Notez que cette solution spécifique fonctionnera dans la vue.)

url: "@Url.Action("UpdateCheckBox", "CeduleGlobale")",

J'espère que cela t'aides. :)

1
Sampath Dilhan

http://localhost:59441/ et
http://testServer/JprApplication/ fonctionnera tous les deux avec votre 

$.ajax({ type: "POST", url: "/CeduleGlobale/UpdateCheckBox", ... 

si votre hébergement dans iis il vous suffit de créer un hôte virtuel dans votre
C:\Windows\System32\drivers\etc\hosts 

file . Ajoutez cette ligne au bas de votre fichier hosts 

127.0.0.1 CeduleGlobale 

 create a new site like so créer un nouveau site comme celui-ci, sélectionner des sites, cliquer avec le bouton droit de la souris et créer un nouveau site

 fill in your details and set the same hostname as you created above 'CeduleGlobale'

remplissez vos coordonnées et définissez le même nom d'hôte que celui que vous avez créé ci-dessus 'CeduleGlobale'

puis déployez votre application MVC sur ce site

0
kudzai zishumba

La réponse de @ Tommy était un bon pointeur, cependant, pour .NET Core, je devais faire les choses un peu différemment, car l'objet Request avait des propriétés différentes. 

Les choses ont été rendues plus difficiles par le déploiement dans un répertoire virtuel, mais en utilisant IIS Express pour le développement; d'où la déclaration if lors de la définition de l'URL de base.

Shared/_Layout.cshtml

<!-- Set the site root for javascript in _Layout.cshtml.-->
@if (!String.IsNullOrWhiteSpace(@Context.Request.PathBase.Value))
{
    /* LIVE - includes virtual directory */
    <script>
        window.siteRoot = "@Context.Request.Scheme" + "://" + "@Context.Request.Host.Value" + "@Context.Request.PathBase.Value" + "/";
    </script>
}
else
{
   /* DEBUG - no virutal directory, e.g. IIS Express */
    <script>
        window.siteRoot = "@Context.Request.Scheme" + "://" + "@Context.Request.Host.Value" + "/";
    </script>
}

Puis à partir de n'importe quel fichier JavaScript

/* from any javascript file */
var url = window.siteRoot + 'MySearch/GetMySearchResults';

$.ajax({
    url: url,
    type: 'GET',
    cache: false,
    data: searchObj,
    success: function (result) {
        alert('yatta!');
    },
    fail: function (e, k, n) {
        alert('hmph!');
    },
    done: function() {
        // hide spinner
    }
});

Évidemment, vous souhaiterez peut-être créer votre propre espace de noms ou quelque chose pour enregistrer pollutingwindow. J'ai essayé de garder l'exemple ci-dessous aussi simple que possible.

0
HockeyJ