简体   繁体   English

如何使用 Ajax 像客户端一样更改服务器端语言 cookies?

[英]How to change server side language cookies like client side using Ajax?

I have two news websites, one in Spanish and one in English:我有两个新闻网站,一个是西班牙语的,一个是英语的:

es.example.com // Spanish
example.com // 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.com/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/´:基于该 URL,我创建了一个“cookie”,其中 URL 的语言将被存储,这是第一个文件夹/子文件夹或目录“/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.com');
}

With this parameter, news will be displayed in Spanish for both the site: es.example.com by the subdomain es or by the URLs in Spanish example.com/es/url-de-la-noticia/ = es使用此参数,两个站点的新闻将以西班牙语显示: es.example.com子域es或西班牙语example.com/es/url-de-la-noticia/ = es中的 URL

//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.但是当我尝试通过Ajax更改语言时出现问题,虽然Ajax代码确实发送和发送信息,但由于某种原因它没有替换cookie,即如果我点击英文,它不会改变它,语言的变化。

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:我想要实现的是语言也可以更改,使用 ajax 在服务器端和客户端上删除或替换 cookies:

 $(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.com/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.com/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.com/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.com/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. language.ini.php文件将负责更改语言,创建各自的 cookies。

<?php
    if (isset($_POST['lang'])) {
        $lang = $_POST['lang'] ?: '';
    
        if ($lang === "en") {
            setcookie ('language', 'en', time()+60*60*24*365, '/', 'example.com');
        } elseif ($lang === "es") {
            setcookie ('language', 'es', time()+60*60*24*365, '/', 'es.example.com');
        }
    }
?>

Server-Side Ajax Call (Fix)服务器端 Ajax 调用(修复)

in your language.ini.php you have to change the line:在您的language.ini.php中,您必须更改以下行:

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

to:至:

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

because if you specify domain of cookie in header, it will be none host-only cookie and, in your both example.com and es.example.com will be use.因为如果您在 header 中指定cookie 的域,它将不是仅主机 cookie ,并且在您的example.comes.example.com中都将使用。

according to RFC6265根据RFC6265

How Cookies Works Cookies 的工作原理

  1. Cookies usually will be requested to set by server-side and browser will save them. Cookies 通常会被服务器端请求设置,浏览器会保存。

  2. The Browser sends Cookie in every Request.浏览器在每个请求中发送 Cookie。

  3. Server can access cookie from the Request from browser.服务器可以从浏览器的请求中访问 cookie。

Cookies Are Essential Since Http is Stateless Protocol , and Server want to Associate a data to a client and use it in next requests . Cookies 是必不可少的,因为Http 是无状态协议,并且服务器希望将数据关联到客户端在下一个请求中使用它。

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在客户端设置 Cookie

and just remove the language.ini.php file.并删除language.ini.php文件。

you can do this by pure Javascript and when the user try to navigate in browser.您可以通过纯 Javascript 以及当用户尝试在浏览器中导航时执行此操作。 his/her requests will be sent via new cookie which javascript has been set.他/她的请求将通过已设置 javascript 的新 cookie 发送。

just you have to be aware TO NOT Enable HTTP-Only Flag on Cookie (Which can prevent Js t manipulate Cookie).只是您必须注意不要在 Cookie 上启用仅 HTTP 标志(这可以防止 Js t 操纵 Cookie)。

Jquery Example: Jquery 示例:

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

instead of sending an ajax request your js can looks like this:而不是发送 ajax 请求,您的 js 可以如下所示:

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

    });
});

Perhaps J. Mick, using the session storage isn't the way to take this forward, maybe using HTML Web Storage is a better fit?也许 J. Mick,使用 session 存储不是推动这一发展的方法,也许使用 HTML Web 存储更合适? 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.至少这样,您不必为了更新 cookie 值等而刷新页面,它可以直接从 JavaScript 写入和读取。

Here's a simple example of writing and reading to the storage via JavaScript.这是一个通过 JavaScript 写入和读取存储的简单示例。 https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_webstorage_local_clickcount https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_webstorage_local_clickcount

Cookies can be sent and received for all requests made from your browser, be it AJAX.可以为从浏览器发出的所有请求发送和接收 Cookies,无论是 AJAX。 You would also be able to update the already set cookie using setcookie which your're already seem to be doing.您还可以使用您似乎已经在做的setcookie来更新已经设置的 cookie。 You can verify the same by looking under Request Headers and Response Headers in Networks tab.您可以通过查看Networks选项卡中的Request HeadersResponse Headers来验证这一点。

There might me something else which is causing your issue.可能还有其他原因导致您的问题。

You appear to have multiple UIs for the same thing.您似乎对同一事物有多个 UI。 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.由于域不同,如果您在不同的域上有不同的会话和 cookies,我不会感到惊讶。

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.但是,为了避免重复代码和功能,至少可以在某个 URL 上使用底层逻辑,从而将 API 暴露给您的西班牙语和英语版本。

Your approach is flawed, because you do not reload the page.您的方法有缺陷,因为您没有重新加载页面。 However, you could solve it if you had these three parts:但是,如果你有这三个部分,你可以解决它:

  • API 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.英语 UI 和西班牙语 UI 都将以类似的方式使用 API,并且在 API 的级别上,实际的英语/西班牙语文本的相关性较低,但 API 将确定语言的级别。

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向 API 发送请求
  • the API generates a token for the other language's site, so the user will not have to manually log in API 为其他语言的站点生成令牌,因此用户不必手动登录
  • a link, containing that token would be returned to the UI包含该令牌的链接将返回给 UI
  • the UI would automatically redirect to the other language's UI UI 会自动重定向到其他语言的 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一旦访问了另一个 URL,就会向 API 发送请求
  • the API validates the token API 验证令牌
  • 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.起初,您的 API 可能非常好,只处理此功能,但理想情况下,将逻辑与两个 UI 分开会很好。

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. 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浏览器。

Using chrome extensions you can modify easily with javascript api the server cookies or any cookie you want使用 chrome 扩展,您可以使用 javascript api 服务器 cookies 或您想要的任何 cookie 轻松修改

https://developers.chrome.com/docs/extensions/reference/cookies/ https://developers.chrome.com/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.通过这种方式,您可以访问任何 cookie 与常规 DOM javascript 不同,后者只会让您访问非 httpOnly cookies 示例。 https://www.cookiepro.com/knowledge/httponly-cookie/ https://www.cookiepro.com/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.当在服务器上创建一个 cookie 并将 httpOnly 属性设置为 true 时,无法从 DOM javascript 读取此 cookie。 But chrome webextension api do have access to these cookies.但是 chrome webextension api 确实可以访问这些 cookies。

Let me know if you need any more help or if this helps you...让我知道您是否需要更多帮助或者这是否对您有帮助...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 客户端和服务器端 cookie - client side and server side cookies AJAX:如何在单击按钮时在客户端和服务器端更改值? - AJAX: How to change a value on client side as well as server side on button click? 客户端cookie是否可被所有人访问,服务器端是否存在cookie? - Are client side cookies accessible by all and are there cookies on the server side 如何在不使用处理程序的情况下使用ajax从客户端将文件发送到服务器端? - How to send file to server side from client side using ajax without using handler? 如何使用JQUERY使用AJAX将Javascript变量(从客户端)发布到PHP文件(服务器端) - How to POST a Javascript Variable (From Client Side) to PHP File (Server Side) with AJAX using JQUERY 从服务器或客户端检查或更改键盘键入语言 - check or change keyboard typing language from server or client side Firebase:如果我使用服务器端 session cookies,如何在客户端获取登录用户的 ID 令牌? - Firebase: How do I get the ID Token for a signed-in user on the client side if I am using server-side session cookies? 如何在客户端更改XML属性,然后在服务器端保存结果? - How to change XML attribute on the client side and then save the result on the server side? 如何从服务器端更改客户端javascript的变量? - How to change client side javascript 's variable from server side? ajax客户端到服务器端 - ajax client-to-server side
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM