admin管理员组

文章数量:1394156

I have two news websites, one in Spanish and one in English:

es.example // Spanish
example // English

But from the main domain (in English) I am integrating a system to be able to show news in another language for example:

example/es/url-de-la-noticia/ // Spanish

Based on that URL, I create one ´cookie´ where the language of the URL will be stored, which is the first folder/subfolder or directory ´/es/´:

//I create the cookies automatically for the subdomain and for the URLs in Spanish.
if($FOLDER_LANG === "es" || $SUBDOMAIN_LANG === "es") {
    setcookie ('language', 'es', time()+60*60*24*365, '/', '.example');
}

With this parameter, news will be displayed in Spanish for both the site: es.example by the subdomain es or by the URLs in Spanish example/es/url-de-la-noticia/ = es

//We verify the existence of the cookie
if(isset($_COOKIE['language'])){
    //We print variables of the language in coincidence of the value that the cookie stores
    if($_COOKIE['language']==='en'){
        $website_title = " | Sitio en español";
        $lang = 'es';
        $language = "es";
    }elseif($_COOKIE['language']==='es'){
        $website_title = " | WebSite Ingles";
        $lang = 'en';
        $language = "en";
    }
} else {
    //In case there is no cookie, I show the English language by default.
    $website_title = " | WebSite Ingles";
    $lang = 'en';
    $language = "en";
}

So far everything seems to be working properly.

But the problem arises when I try to change the language through Ajax, although the Ajax code does send and send information, for some reason it does not replace the cookie, that is, if I click on the English language, it does not change it, the change of language.

What I want to achieve is that the language can also be changed, removing or replacing the cookies both on the server side and the client side using ajax:

$(function(){
    var tnum = 'en';
    
    $(document).click( function(e) {
        $('.language, .more_lang').removeClass('active');
    });

    $('.language .current_lang').click(function(e){
        e.stopPropagation();
        $(this).parent().toggleClass('active');
        setTimeout(function(){
            $('.more_lang').toggleClass('active');
        }, 5);
    });

    $('.more_lang .lang').click(function(){
        $(this).addClass('selected').siblings().removeClass('selected');
        $('.more_lang').removeClass('active');

        var img = $(this).find('img').attr('src');
        var lang = $(this).attr('data-value');
        var tnum = lang;

        $('.current_lang .lang-txt').text(lang);
        $('.current_lang img').attr('src', img);

        //if(lang == 'ar'){}
    });
});

$(function() {
    $(".lang").click(function(e) {
        e.preventDefault();
        var language = $(this).attr('data-value');
        var postData={lang: language};

        var request = $.ajax({
            method : 'POST',
            url    : 'language.ini.php',
            data   : postData,
            dataType: "html"
        });
        request.done(function(data) {
            $(".resultado").html(data);
        });
        request.fail(function(jqXHR, textStatus) {
            alert("Ocurrió un error: " + textStatus);
        });
    });
});
body{
    margin:0;
  padding:0;
  color:#444444;
  font-family: 'News Cycle', sans-serif;
}

.language{
  position:fixed;
  z-index:1;
  top:20px;
  left:20px;
  font-size:16px;
  background:#fff;  
  border-radius:4px;
}

.current_lang{
  cursor:pointer;
  text-transform:uppercase;
  overflow:hidden;
}

.lang{
    padding:10px 15px;
}

.lang.selected{
  display:none;
}

.lang img, 
.lang span.lang-txt{
  display:inline-block;
  margin-left:5px;
  vertical-align:middle;
}

.lang span.lang-txt{
   position:relative;
  top:-1px;
  font-weight:700;
}

.lang img{
  width:20px;
  margin-left:0;
}

.lang span span{
  color:#999;
  font-weight:400;
}

.lang span.fa{
  font-size:12px;
  position:relative;
  top:-1px;
  margin-left:3px;
}


/*more lang*/
.more_lang{
  transform:translateY(-20px);
  opacity:0;
  cursor:pointer;
  display:none;
   -webkit-transition: all .3s cubic-bezier(.25, 1.15, .35, 1.15);
    -moz-transition:    all .3s cubic-bezier(.25, 1.15, .35, 1.15);
    -o-transition:      all .3s cubic-bezier(.25, 1.15, .35, 1.15);
    -ms-transition:     all .3s cubic-bezier(.25, 1.15, .35, 1.15);
    transition:         all .3s cubic-bezier(.25, 1.15, .35, 1.15);
}

.language.active .more_lang{
  display:block; 
}

.more_lang.active{
  opacity:1;
   transform:translateY(-0px);
}

.more_lang .lang:hover{
  background:#5766b2;
  color:#fff;
}

.more_lang .lang:hover span{
  color:#fff;
}

.language:hover,
.language.active,
.content a:hover{
  box-shadow:rgba(0,0,0,0.2) 0 5px 15px;  
  -webkit-transition: all 0.3s cubic-bezier(0,.99,.44,.99);
    -moz-transition:    all 0.3s cubic-bezier(0,.99,.44,.99);
    -o-transition:      all 0.3s cubic-bezier(0,.99,.44,.99);
    -ms-transition:     all 0.3s cubic-bezier(0,.99,.44,.99);
    transition:         all 0.3s cubic-bezier(0,.99,.44,.99);
  
}

.language.active .lang{
  border-bottom:1px solid #eaeaea;
}

/*CONTENT*/
.content{
  width:100%;
  max-width:400px;
  position:absolute;
  top:50%;
  left:50%;
  -ms-transform: translateX(-50%) translateY(-50%);
  -webkit-transform: translate(-50%,-50%);
  transform: translate(-50%,-50%);
  border-radius:2px;
  padding:20px;
  -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
  
  text-align:center;
}

.content h1, 
.content h2, 
.content p{
  margin:0;
}

.content p{
   line-height:22px;
  text-align:left;
  margin-top:15px;
}


.content div.ct-img{
  width:150px;
  height:150px;
  overflow:hidden;
  border-radius:50%;
  margin:0 auto 10px;
}

.content div img{
  height:100%;
  position:relative;
  left:-30px;
}

.content a{
  padding: 8px 15px 10px;
   border-radius:4px;
  background:#5766b2;
  color:#fff;
  text-decoration:none;
  display:inline-block;
  margin-top:25px;
  position:relative;
  overflow:hidden;
}

.content a:active{
  transform: scale(0.9);
   -webkit-transform: scale(0.9);
  -moz-transform: scale(0.9);
}

/*RTL*/
body[dir="rtl"] .language{
  right:20px;
  left:auto;
}

body[dir="rtl"] .lang span.fa{
  margin-right:3px;
  margin-left:0;
}

body[dir="rtl"] .lang .lang-txt{
  margin-right:5px;
  margin-left:0;
}

body[dir="rtl"] .content div img{
  left:auto;
  right:-30px;
}


body[dir="rtl"] .content p{
  text-align:right;
}

body[dir="rtl"] .lang span span{
  float:left;
  margin-right:5px;
}
<script src=".3.1/jquery.min.js"></script>
<div class="language">
        <div class="current_lang">
            <div class="lang" data-value='en'>
                <img src=".svg">
                <span class="lang-txt">EN</span> 
                <span class="fa fa-chevron-down chevron"></span>
            </div>
        </div>
        <div class="more_lang">    
            <div class="lang selected" data-value='en'>
                <img src=".svg">
                <span class="lang-txt">English<span> (US)</span></span>
            </div>
            <div class="lang" data-value='es'>
                <img src=".svg">
                <span class="lang-txt">Español</span>
            </div>
        </div>
    </div>

I have two news websites, one in Spanish and one in English:

es.example. // Spanish
example. // English

But from the main domain (in English) I am integrating a system to be able to show news in another language for example:

example./es/url-de-la-noticia/ // Spanish

Based on that URL, I create one ´cookie´ where the language of the URL will be stored, which is the first folder/subfolder or directory ´/es/´:

//I create the cookies automatically for the subdomain and for the URLs in Spanish.
if($FOLDER_LANG === "es" || $SUBDOMAIN_LANG === "es") {
    setcookie ('language', 'es', time()+60*60*24*365, '/', '.example.');
}

With this parameter, news will be displayed in Spanish for both the site: es.example. by the subdomain es or by the URLs in Spanish example./es/url-de-la-noticia/ = es

//We verify the existence of the cookie
if(isset($_COOKIE['language'])){
    //We print variables of the language in coincidence of the value that the cookie stores
    if($_COOKIE['language']==='en'){
        $website_title = " | Sitio en español";
        $lang = 'es';
        $language = "es";
    }elseif($_COOKIE['language']==='es'){
        $website_title = " | WebSite Ingles";
        $lang = 'en';
        $language = "en";
    }
} else {
    //In case there is no cookie, I show the English language by default.
    $website_title = " | WebSite Ingles";
    $lang = 'en';
    $language = "en";
}

So far everything seems to be working properly.

But the problem arises when I try to change the language through Ajax, although the Ajax code does send and send information, for some reason it does not replace the cookie, that is, if I click on the English language, it does not change it, the change of language.

What I want to achieve is that the language can also be changed, removing or replacing the cookies both on the server side and the client side using ajax:

$(function(){
    var tnum = 'en';
    
    $(document).click( function(e) {
        $('.language, .more_lang').removeClass('active');
    });

    $('.language .current_lang').click(function(e){
        e.stopPropagation();
        $(this).parent().toggleClass('active');
        setTimeout(function(){
            $('.more_lang').toggleClass('active');
        }, 5);
    });

    $('.more_lang .lang').click(function(){
        $(this).addClass('selected').siblings().removeClass('selected');
        $('.more_lang').removeClass('active');

        var img = $(this).find('img').attr('src');
        var lang = $(this).attr('data-value');
        var tnum = lang;

        $('.current_lang .lang-txt').text(lang);
        $('.current_lang img').attr('src', img);

        //if(lang == 'ar'){}
    });
});

$(function() {
    $(".lang").click(function(e) {
        e.preventDefault();
        var language = $(this).attr('data-value');
        var postData={lang: language};

        var request = $.ajax({
            method : 'POST',
            url    : 'language.ini.php',
            data   : postData,
            dataType: "html"
        });
        request.done(function(data) {
            $(".resultado").html(data);
        });
        request.fail(function(jqXHR, textStatus) {
            alert("Ocurrió un error: " + textStatus);
        });
    });
});
body{
    margin:0;
  padding:0;
  color:#444444;
  font-family: 'News Cycle', sans-serif;
}

.language{
  position:fixed;
  z-index:1;
  top:20px;
  left:20px;
  font-size:16px;
  background:#fff;  
  border-radius:4px;
}

.current_lang{
  cursor:pointer;
  text-transform:uppercase;
  overflow:hidden;
}

.lang{
    padding:10px 15px;
}

.lang.selected{
  display:none;
}

.lang img, 
.lang span.lang-txt{
  display:inline-block;
  margin-left:5px;
  vertical-align:middle;
}

.lang span.lang-txt{
   position:relative;
  top:-1px;
  font-weight:700;
}

.lang img{
  width:20px;
  margin-left:0;
}

.lang span span{
  color:#999;
  font-weight:400;
}

.lang span.fa{
  font-size:12px;
  position:relative;
  top:-1px;
  margin-left:3px;
}


/*more lang*/
.more_lang{
  transform:translateY(-20px);
  opacity:0;
  cursor:pointer;
  display:none;
   -webkit-transition: all .3s cubic-bezier(.25, 1.15, .35, 1.15);
    -moz-transition:    all .3s cubic-bezier(.25, 1.15, .35, 1.15);
    -o-transition:      all .3s cubic-bezier(.25, 1.15, .35, 1.15);
    -ms-transition:     all .3s cubic-bezier(.25, 1.15, .35, 1.15);
    transition:         all .3s cubic-bezier(.25, 1.15, .35, 1.15);
}

.language.active .more_lang{
  display:block; 
}

.more_lang.active{
  opacity:1;
   transform:translateY(-0px);
}

.more_lang .lang:hover{
  background:#5766b2;
  color:#fff;
}

.more_lang .lang:hover span{
  color:#fff;
}

.language:hover,
.language.active,
.content a:hover{
  box-shadow:rgba(0,0,0,0.2) 0 5px 15px;  
  -webkit-transition: all 0.3s cubic-bezier(0,.99,.44,.99);
    -moz-transition:    all 0.3s cubic-bezier(0,.99,.44,.99);
    -o-transition:      all 0.3s cubic-bezier(0,.99,.44,.99);
    -ms-transition:     all 0.3s cubic-bezier(0,.99,.44,.99);
    transition:         all 0.3s cubic-bezier(0,.99,.44,.99);
  
}

.language.active .lang{
  border-bottom:1px solid #eaeaea;
}

/*CONTENT*/
.content{
  width:100%;
  max-width:400px;
  position:absolute;
  top:50%;
  left:50%;
  -ms-transform: translateX(-50%) translateY(-50%);
  -webkit-transform: translate(-50%,-50%);
  transform: translate(-50%,-50%);
  border-radius:2px;
  padding:20px;
  -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
  
  text-align:center;
}

.content h1, 
.content h2, 
.content p{
  margin:0;
}

.content p{
   line-height:22px;
  text-align:left;
  margin-top:15px;
}


.content div.ct-img{
  width:150px;
  height:150px;
  overflow:hidden;
  border-radius:50%;
  margin:0 auto 10px;
}

.content div img{
  height:100%;
  position:relative;
  left:-30px;
}

.content a{
  padding: 8px 15px 10px;
   border-radius:4px;
  background:#5766b2;
  color:#fff;
  text-decoration:none;
  display:inline-block;
  margin-top:25px;
  position:relative;
  overflow:hidden;
}

.content a:active{
  transform: scale(0.9);
   -webkit-transform: scale(0.9);
  -moz-transform: scale(0.9);
}

/*RTL*/
body[dir="rtl"] .language{
  right:20px;
  left:auto;
}

body[dir="rtl"] .lang span.fa{
  margin-right:3px;
  margin-left:0;
}

body[dir="rtl"] .lang .lang-txt{
  margin-right:5px;
  margin-left:0;
}

body[dir="rtl"] .content div img{
  left:auto;
  right:-30px;
}


body[dir="rtl"] .content p{
  text-align:right;
}

body[dir="rtl"] .lang span span{
  float:left;
  margin-right:5px;
}
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="language">
        <div class="current_lang">
            <div class="lang" data-value='en'>
                <img src="https://image.flaticon./icons/svg/299/299722.svg">
                <span class="lang-txt">EN</span> 
                <span class="fa fa-chevron-down chevron"></span>
            </div>
        </div>
        <div class="more_lang">    
            <div class="lang selected" data-value='en'>
                <img src="https://image.flaticon./icons/svg/299/299722.svg">
                <span class="lang-txt">English<span> (US)</span></span>
            </div>
            <div class="lang" data-value='es'>
                <img src="https://image.flaticon./icons/svg/299/299820.svg">
                <span class="lang-txt">Español</span>
            </div>
        </div>
    </div>

The language.ini.php file will be in charge of changing the language, creating their respective cookies.

<?php
    if (isset($_POST['lang'])) {
        $lang = $_POST['lang'] ?: '';
    
        if ($lang === "en") {
            setcookie ('language', 'en', time()+60*60*24*365, '/', 'example.');
        } elseif ($lang === "es") {
            setcookie ('language', 'es', time()+60*60*24*365, '/', 'es.example.');
        }
    }
?>
Share Improve this question edited Dec 8, 2020 at 3:41 asked Dec 7, 2020 at 20:39 user10360773user10360773 7
  • 2 Do you refresh the page after the Ajax call? JavaScript doesn't affect the cookies set by the header responses of the server. – Altimus Prime Commented Dec 10, 2020 at 0:24
  • @AltimusPrime wow !! when updating the page I see that if it changes ... then friend, what changes should I make to the ajax code so that it reloads the page so as not to be refreshing the page manually ... request.done (function (data) – user10360773 Commented Dec 10, 2020 at 6:51
  • 1 yes, AJAX call does not replace the cookie. An alternative approach might be to send a custom header in response, then handle it on client and set cookie via document.cookie modification. – michal.jakubeczy Commented Dec 10, 2020 at 7:09
  • @michal.jakubeczy I can not understand it... :/ – user10360773 Commented Dec 10, 2020 at 10:43
  • @J.Mick How do you make the ajax call? If refreshing the page upon pletion of the ajax call serves your purpose then location.reload(); on a successful ajax call could potentially serve your purpose. If you need to repopulate the content of the page without refreshing it I might need to see your client side. – Altimus Prime Commented Dec 11, 2020 at 0:31
 |  Show 2 more ments

5 Answers 5

Reset to default 3 +50

Server-Side Ajax Call (Fix)

in your language.ini.php you have to change the line:

setcookie ('language', 'es', time()+60*60*24*365, '/', 'es.example.');

to :

 setcookie ('language', 'es', time()+60*60*24*365, '/', 'example.');

because if you specify domain of cookie in header, it will be none host-only cookie and, in your both example. and es.example. will be use.

according to RFC6265

How Cookies Works

  1. Cookies usually will be requested to set by server-side and browser will save them.

  2. The Browser sends Cookie in every Request.

  3. Server can access cookie from the Request from browser.

Cookies Are Essential Since Http is Connection-less Protocol, and Server want to Associate a data to a client and use it in next requests .

A Preferable Scenario (Desired Solution)

as long as your user decide to view your site in which language they prefer. and your server will not doing nothing with it (no controls, no security threads).

you can use a shortcut .

Set The Cookie in Your Client-side

and just remove the language.ini.php file.

you can do this by pure Javascript and when the user try to navigate in browser. his/her requests will be sent via new cookie which javascript has been set.

just you have to be aware TO NOT Enable HTTP-Only Flag on Cookie (Which can prevent Js t manipulate Cookie).

Jquery Example:

$.cookie('language', '', { expires: 365, path: '/', domain: 'example.' });

instead of sending an ajax request your js can looks like this:

$(function() {
    $(".lang").click(function(e) {
        e.preventDefault();
        var language = $(this).attr('data-value');
        $.cookie('language', language, { expires: 365, path: '/', domain: 'example.' });

    });
});

Perhaps J. Mick, using the session storage isn't the way to take this forward, maybe using HTML Web Storage is a better fit? At least that way, you don't have to page fresh in order to update cookie values etc, it can be wrote and read straight from JavaScript.

Here's a simple example of writing and reading to the storage via JavaScript. https://www.w3schools./html/tryit.asp?filename=tryhtml5_webstorage_local_clickcount

Cookies can be sent and received for all requests made from your browser, be it AJAX. You would also be able to update the already set cookie using setcookie which your're already seem to be doing. You can verify the same by looking under Request Headers and Response Headers in Networks tab.

There might me something else which is causing your issue.

You appear to have multiple UIs for the same thing. You have an English and a Spanish website. Since the domains are different, I would not be surprised if you had different sessions and cookies on the separate domains.

However, in order to avoid duplicating code and features, at least the underlying logic could be available at a certain URL, exposing an API both to your Spanish and English version.

Your approach is flawed, because you do not reload the page. However, you could solve it if you had these three parts:

  • API
  • English UI
  • Spanish UI

Both the English UI and the Spanish UI would use the API in a similar manner and on the level of the API the actual English/Spanish texts would be less relevant, but the API would be the level which would determine the language.

So, if you click on the English button on the Spanish site or the Spanish button on the English site, then the following should happen:

  • a request is sent to the API
  • the API generates a token for the other language's site, so the user will not have to manually log in
  • a link, containing that token would be returned to the UI
  • the UI would automatically redirect to the other language's UI
  • this ensures that the domain is correct and the page is loaded
  • once the other URL is visited, a request is sent to the API
  • the API validates the token
  • if the token was valid, then the user is allowed into the system and the token is destroyed

This is how I would approach this. At first your API can be very thing, handling only this feature, but ideally it would be great to separate the logic from the two UIs.

Since this solution would involve sending AJAX requests to the API, which will be on a different URL, you will need to make sure that you have the correct HTML headers that allow your page to send requests to the API without violating the CORS policy of the browser.

Using chrome extensions you can modify easily with javascript api the server cookies or any cookie you want

https://developers.chrome./docs/extensions/reference/cookies/

This way you can access any cookie Unlike regular DOM javascript which will get you access only to non httpOnly cookies for examples. https://www.cookiepro./knowledge/httponly-cookie/

When a cookie was created at the server with httpOnly property set to true Then this cookie cannot be read from DOM javascript. But chrome webextension api do have access to these cookies.

Let me know if you need any more help or if this helps you...

本文标签: javascriptHow to change server side language cookies like client side using AjaxStack Overflow