不再让梦枯萎

文章 评论 浏览 31

不再让梦枯萎 2025-02-02 19:13:12

下面的代码访问带有ID“测试”的段落,并将“ TestVariable”的值打印在其中。

var testVariable = "hello";
document.getElementById("test").innerHTML = testVariable;
<p id="test"></p>

The code below accesses the paragraph with id "test" and print the value of "testVariable" into it.

var testVariable = "hello";
document.getElementById("test").innerHTML = testVariable;
<p id="test"></p>

如何将JS变量渲染到HTML元素中

不再让梦枯萎 2025-02-02 18:54:51

线路的概念是未定义的。如果您的DIV宽度为400px,则测试文本为4行,如果您的DIV为900px,则文本将为2行。

首先,您需要定义自己的行,就像每200个充电器或每20个单词一样,然后将每200个ACHERETER剪下弦,然后将每个字符都放入一个阵列中。

然后,您为您的线条字符串编写了一个for循环。如果每个都包含您的目标字符串,您可以知道并通过该行做一些事情

the concept of line is someting that is not defined. if you have a div with width 400px a test text will be 4 lines and if you have a div of 900px your text will be 2 lines.

first you need to define your line, like every 200 charecters or every 20 words, then you cut your string per 200 chareter and put each inside an array.

then you have write a for loop for your array of line strings. if each contains your target string, you can know and do something with that line

如何在字符串中匹配字符串时如何读取

不再让梦枯萎 2025-02-02 14:17:48

基于您的问题,为什么不使用 image_compression_flutter_flutter 在选择<<<代码>图像Quality:100

通过使用另一个压缩功能,您可以压缩图像并将压缩图像作为输出。

Based on your question why don't you use Image_compression_flutter to compress image after you have selected the image with imageQuality: 100
.

By using another compression function , you can compress the image and get the compressed image as output.

如何使用image_picker压缩图像 - 颤动

不再让梦枯萎 2025-02-02 13:02:26

要绑定data.frames的列表,然后将列表名称存储为新列,一种方便的方法是在 dplyr :: bind_rows()中设置arg .id

library(dplyr)

mget(apropos("^mydf_")) %>%
  bind_rows(.id = "name") %>%
  count(name, wt = n) %>%
  filter(n > 0)

#     name n
# 1 mydf_1 2
# 2 mydf_3 3

To bind a list of data.frames and store the list names as a new column, a convenient way is to set the arg .id in dplyr::bind_rows().

library(dplyr)

mget(apropos("^mydf_")) %>%
  bind_rows(.id = "name") %>%
  count(name, wt = n) %>%
  filter(n > 0)

#     name n
# 1 mydf_1 2
# 2 mydf_3 3

作为IDS,将数据帧的名称从循环返回新数据框架

不再让梦枯萎 2025-02-02 06:35:42

我认为,密码需要正确哈希,因为Django并未将原始密码存储。

您可以使用 cleaned_data ,并且需要正确哈希密码,因此您可以从django.contrib.auth.hashers import Import Import import import import sake_password() make_password 。

因此,使用当前的代码确实在 views.pys.py 中进行修改。

from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password

def register(request, self):
    if request.method == 'POST':
        form = CustomUserForm(request.POST)
        if form.is_valid():
            username=form.cleaned_data['username']
            email=form.cleaned_data['email']
            password=make_password(form.cleaned_data['password1'])
            data=User(username=username,email=email,password=password)
            data.save()            
            messages.success(request, "Registered Successfully")
            return redirect('/login/')
    else: #Here GET condition
        form = CustomUserForm()
    context = {'form': form}
    return render(request, 'auth/register.html', context)

注意:您必须在每个路线结束时给出/

I think, password needs to be hashed properly, as raw passwords aren't stored by django.

You can make use of cleaned_data,and you need to hash the password properly, so you can use make_password() from from django.contrib.auth.hashers import make_password.

So, with your current code do following modifications in views.py.

from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password

def register(request, self):
    if request.method == 'POST':
        form = CustomUserForm(request.POST)
        if form.is_valid():
            username=form.cleaned_data['username']
            email=form.cleaned_data['email']
            password=make_password(form.cleaned_data['password1'])
            data=User(username=username,email=email,password=password)
            data.save()            
            messages.success(request, "Registered Successfully")
            return redirect('/login/')
    else: #Here GET condition
        form = CustomUserForm()
    context = {'form': form}
    return render(request, 'auth/register.html', context)

Note: You must give / at the end of every route.

password1和password2不保存在django表单中

不再让梦枯萎 2025-02-02 00:11:04

手动运行触发后立即开始。
计划的运行受气流调度机械设备的约束。我在问题和预定日期中的问题Apache Airflow

在您的情况下,的开始日期2022-05-03 带有 0 21 * * * * * * 的间隔意味着第一个运行将在上开始2022-05-04 21:00 。此运行的 execution_date 将为 2022-05-03 21:00
因此,如果您希望第一次运行以 2022-05-03 21:00 进行:或者,您需要设置:

start_date=pendulum.datetime(2022, 5, 2, tz="UTC"),
schedule_interval="0 21 * * *",

或者,如果要指定精确的运行时间,则需要使用

Manual runs start as soon as you trigger it.
Scheduled runs are subject to Airflow scheduling mechanisem. I explained it in Problem with start date and scheduled date in Apache Airflow

In your case start date of 2022-05-03 with interval of 0 21 * * * means that the first run will start on 2022-05-04 21:00. The execution_date of this run will be 2022-05-03 21:00.
So if you wanted the first run to start on 2022-05-03 21:00 you need to set:

start_date=pendulum.datetime(2022, 5, 2, tz="UTC"),
schedule_interval="0 21 * * *",

Alternatively, if you want to specify exact run times you will need to use Timetables then you can customize DAG Scheduling with Timetables.

气流预定的DAG现在按预期工作

不再让梦枯萎 2025-02-01 14:12:08

即使您不想退还任何有效载荷,也必须用 res.end() res.render(...) 或...

用户是否将用户重定向到另一页不取决于您发送的内容,而是浏览器如何提出请求:

  • 如果请求是提交HTML表单的结果,您无法避免浏览器导航,但是您可以让服务器再次返回同一HTML页面。
  • 如果请求是xmlhttprequest,例如通过 axios.post 制作,浏览器将根本不会导航,而是简单地接收响应,也许可以基于它更新HTML页面。如果您没有任何响应主体,那似乎是更好的选择。这也是肖恩·劳顿(Sean Lawton)的回答意味着“ //发送邮政请求”的内容。

Even if you don't want to send any payload back, you must end the request with res.end() or res.render(...) or ...

Whether the user is redirected to another page does not depend on what you send back but on how the browser makes the request:

  • If the request is the result of submitting an HTML form, you cannot avoid that the browser navigates, but you could have your server return the same HTML page again.
  • If the request is an XMLHttpRequest, for example made via axios.post, the browser will not navigate at all but simply receive the response and perhaps update the HTML page based on it. If you don't have any response body, that seems the better option. This is also what Sean Lawton's answer implies where it says "// send post request".

在数据库中插入数据后,如何修复网页加载? (Express,节点)

不再让梦枯萎 2025-02-01 13:40:29
SELECT DATEADD(HOUR, 8, CAST(CAST(GETDATE()+1 AS DATE) AS DATETIME))
SELECT DATEADD(HOUR, 8, CAST(CAST(GETDATE()+1 AS DATE) AS DATETIME))

如何使用SQL代码获得日期的特定时间

不再让梦枯萎 2025-02-01 03:45:42

您只需在 Label 中只需使用 textBlock

<Label>
   <TextBlock>
      <Run Text="Text1"/>
      <Run Text="Text2"/>
   </TextBlock>
</Label>

You can just simply use TextBlock inside the Label

<Label>
   <TextBlock>
      <Run Text="Text1"/>
      <Run Text="Text2"/>
   </TextBlock>
</Label>

WPF:如何将字符串绑定到标签内容的动态资源

不再让梦枯萎 2025-01-31 12:06:10

聚会很晚,但是我今天在探索这个问题,并注意到许多答案并没有完全解决JavaScript如何处理范围,这实际上是归结为归结为。

因此,正如许多其他提到的问题,问题在于,内部函数正在引用相同的 i 变量。那么,为什么我们不只是创建每个局部变量的新局部变量,而是将内部函数引用呢?

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (var i = 0; i < 3; i++) {
    var ilocal = i; //create a new local variable
    funcs[i] = function() {
        console.log("My value: " + ilocal); //each should reference its own local variable
    };
}
for (var j = 0; j < 3; j++) {
    funcs[j]();
}

就像以前一样,每个内部函数输出了分配给 i 的最后一个值,现在每个内部函数仅输出分配给 iLocal 的最后一个值。但是,每个迭代都不应该拥有自己的 ilocal 吗?

事实证明,这就是问题。每个迭代都共享相同的范围,因此第一个迭代在第一个迭代之后只是覆盖 iLocal 。来自

重要:JavaScript没有块范围。带有块引入的变量范围范围范围范围内包含的函数或脚本,并且将它们设置为块本身的效果持续存在。换句话说,块语句不会引入范围。尽管“独立”块是有效的语法,但您不想在JavaScript中使用独立的块,因为他们不做您认为自己做的事情,如果您认为他们在C或Java中做这样的块。

重申强调:

JavaScript没有块范围。带有块引入的变量范围范围范围范围或脚本

我们可以通过在每次迭代中声明 ilocal 来查看它:

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (var i = 0; i < 3; i++) {
  console.log(ilocal);
  var ilocal = i;
}

这就是为什么此错误如此棘手的原因。即使您正在重新启动变量,JavaScript也不会出错,JSlint甚至不会发出警告。这也是解决此问题的最佳方法是利用闭合的原因,这实际上是在JavaScript中,内部功能可以访问外部变量,因为内部范围“包围”外部范围。

“

这也意味着内部函数“保持“外部变量”并保持它们的生命,即使外部函数返回。为了利用它,我们创建和调用包装器函数纯粹是为了制作新范围,在新范围中声明 iLocal ,然后返回使用 ilocal 的内部函数(更多说明)以下):

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (var i = 0; i < 3; i++) {
    funcs[i] = (function() { //create a new scope using a wrapper function
        var ilocal = i; //capture i into a local var
        return function() { //return the inner function
            console.log("My value: " + ilocal);
        };
    })(); //remember to run the wrapper function
}
for (var j = 0; j < 3; j++) {
    funcs[j]();
}

在包装器函数中创建内部函数可为内部函数提供一个私有环境,只有它才能访问,即“闭合”。因此,每次我们调用包装器函数时,我们都会使用其自己的独立环境创建一个新的内部函数,以确保 ilocal 变量不会碰撞并相互覆盖。一些次要的优化给出了许多其他用户给出的最终答案:

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (var i = 0; i < 3; i++) {
    funcs[i] = wrapper(i);
}
for (var j = 0; j < 3; j++) {
    funcs[j]();
}
//creates a separate environment for the inner function
function wrapper(ilocal) {
    return function() { //return the inner function
        console.log("My value: " + ilocal);
    };
}

更新

使用ES6现在的主流,我们现在可以使用新的关键字来创建块划分变量:

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (let i = 0; i < 3; i++) { // use "let" to declare "i"
    funcs[i] = function() {
        console.log("My value: " + i); //each should reference its own local variable
    };
}
for (var j = 0; j < 3; j++) { // we can use "var" here without issue
    funcs[j]();
}

看看现在有多容易!有关更多信息,请参见这个答案,我的信息基于。

Bit late to the party, but I was exploring this issue today and noticed that many of the answers don't completely address how Javascript treats scopes, which is essentially what this boils down to.

So as many others mentioned, the problem is that the inner function is referencing the same i variable. So why don't we just create a new local variable each iteration, and have the inner function reference that instead?

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (var i = 0; i < 3; i++) {
    var ilocal = i; //create a new local variable
    funcs[i] = function() {
        console.log("My value: " + ilocal); //each should reference its own local variable
    };
}
for (var j = 0; j < 3; j++) {
    funcs[j]();
}

Just like before, where each inner function outputted the last value assigned to i, now each inner function just outputs the last value assigned to ilocal. But shouldn't each iteration have it's own ilocal?

Turns out, that's the issue. Each iteration is sharing the same scope, so every iteration after the first is just overwriting ilocal. From MDN:

Important: JavaScript does not have block scope. Variables introduced with a block are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. In other words, block statements do not introduce a scope. Although "standalone" blocks are valid syntax, you do not want to use standalone blocks in JavaScript, because they don't do what you think they do, if you think they do anything like such blocks in C or Java.

Reiterated for emphasis:

JavaScript does not have block scope. Variables introduced with a block are scoped to the containing function or script

We can see this by checking ilocal before we declare it in each iteration:

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (var i = 0; i < 3; i++) {
  console.log(ilocal);
  var ilocal = i;
}

This is exactly why this bug is so tricky. Even though you are redeclaring a variable, Javascript won't throw an error, and JSLint won't even throw a warning. This is also why the best way to solve this is to take advantage of closures, which is essentially the idea that in Javascript, inner functions have access to outer variables because inner scopes "enclose" outer scopes.

Closures

This also means that inner functions "hold onto" outer variables and keep them alive, even if the outer function returns. To utilize this, we create and call a wrapper function purely to make a new scope, declare ilocal in the new scope, and return an inner function that uses ilocal (more explanation below):

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (var i = 0; i < 3; i++) {
    funcs[i] = (function() { //create a new scope using a wrapper function
        var ilocal = i; //capture i into a local var
        return function() { //return the inner function
            console.log("My value: " + ilocal);
        };
    })(); //remember to run the wrapper function
}
for (var j = 0; j < 3; j++) {
    funcs[j]();
}

Creating the inner function inside a wrapper function gives the inner function a private environment that only it can access, a "closure". Thus, every time we call the wrapper function we create a new inner function with it's own separate environment, ensuring that the ilocal variables don't collide and overwrite each other. A few minor optimizations gives the final answer that many other SO users gave:

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (var i = 0; i < 3; i++) {
    funcs[i] = wrapper(i);
}
for (var j = 0; j < 3; j++) {
    funcs[j]();
}
//creates a separate environment for the inner function
function wrapper(ilocal) {
    return function() { //return the inner function
        console.log("My value: " + ilocal);
    };
}

Update

With ES6 now mainstream, we can now use the new let keyword to create block-scoped variables:

//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};

var funcs = {};
for (let i = 0; i < 3; i++) { // use "let" to declare "i"
    funcs[i] = function() {
        console.log("My value: " + i); //each should reference its own local variable
    };
}
for (var j = 0; j < 3; j++) { // we can use "var" here without issue
    funcs[j]();
}

Look how easy it is now! For more information see this answer, which my info is based off of.

javaScript在循环内部关闭&#x2013;简单的实践例子

不再让梦枯萎 2025-01-31 11:22:44

一个简单的选择是将字符串分为3个部分(这是 regexp_substr 做的),然后将前3个字符完好无损,而其余的则由三个点表示。将这些碎片连接到最终结果中。

示例数据:

SQL> with test (col) as
  2    (select 'ANDREI/TOKAREV MR' from dual union all
  3     select 'MIRANOVA/OLGA MS' from dual
  4    )

查询从这里开始:

  5  select col, substr(regexp_substr(col, '\w+', 1, 1), 1, 3) || '...' ||'/'||
  6              substr(regexp_substr(col, '\w+', 1, 2), 1, 3) || '...' ||' '||
  7              regexp_substr(col, '\w+', 1, 3) as result
  8  from test;

COL               RESULT
----------------- ----------------------------------------
ANDREI/TOKAREV MR AND.../TOK... MR
MIRANOVA/OLGA MS  MIR.../OLG... MS

SQL>

A simple option is to split that string into 3 parts (that's what regexp_substr does), and then leave the first 3 characters intact, while the rest is represented by three dots. Concatenate these pieces into the final result.

Sample data:

SQL> with test (col) as
  2    (select 'ANDREI/TOKAREV MR' from dual union all
  3     select 'MIRANOVA/OLGA MS' from dual
  4    )

Query begins here:

  5  select col, substr(regexp_substr(col, '\w+', 1, 1), 1, 3) || '...' ||'/'||
  6              substr(regexp_substr(col, '\w+', 1, 2), 1, 3) || '...' ||' '||
  7              regexp_substr(col, '\w+', 1, 3) as result
  8  from test;

COL               RESULT
----------------- ----------------------------------------
ANDREI/TOKAREV MR AND.../TOK... MR
MIRANOVA/OLGA MS  MIR.../OLG... MS

SQL>

字符蒙版 - SQL(Oracle)中的列

不再让梦枯萎 2025-01-31 09:38:44

您可以将 type_index 包裹在带有比较器的自定义类型中,该比较器得出所需的顺序。

该示例来自 cppreference 使用 std :: map 而不是 std :: unordered_map ,并且使用自定义比较器:

#include <iostream>
#include <typeinfo>
#include <typeindex>
#include <map>
#include <string>
#include <memory>
 
struct A {
    virtual ~A() {}
};
 
struct B : A {};
struct C : A {};

struct my_type_index {
    std::type_index index = std::type_index(typeid(void));
    my_type_index() = default;
    my_type_index(std::type_index i) : index(i) {}
    bool operator<(const my_type_index& other) const {
        static std::map< std::type_index,int> rank{
            { std::type_index(typeid(A)) , 1},
            { std::type_index(typeid(B)),  2},
            { std::type_index(typeid(double)),  3},
            { std::type_index(typeid(int)),  4},
            { std::type_index(typeid(C)),  5}
        };        
        return rank[index] < rank[other.index];
    }
};


int main()
{
    std::map<my_type_index, std::string> type_names;
 
    type_names[std::type_index(typeid(int))] = "int";
    type_names[std::type_index(typeid(double))] = "double";
    type_names[std::type_index(typeid(A))] = "A";
    type_names[std::type_index(typeid(B))] = "B";
    type_names[std::type_index(typeid(C))] = "C";
   
    for (const auto& e : type_names) {
        std::cout << e.first.index.name() << " " << e.second << "\n";
    }
}

utput

1A A
1B B
d double
i int
1C C

随着FrançoisAndrieux建议的改进:

struct my_type_index {
    std::type_index index = std::type_index(typeid(void));
    int rank = 0;
    my_type_index() = default;
    my_type_index(std::type_index i) : index(i) {
        auto it = ranks.find(i);
        if (it != ranks.end()) rank = it->second;
    }
    
    static const std::map<std::type_index,int> ranks;
    
    bool operator<(const my_type_index& other) const {        
        return rank < other.rank;
    }
};

const std::map<std::type_index,int> my_type_index::ranks = [](){
    std::map<std::type_index,int> result;
    std::type_index index_order[] = {
        std::type_index(typeid(A)),
        std::type_index(typeid(B)),
        std::type_index(typeid(double)),
        std::type_index(typeid(int)),
        std::type_index(typeid(C)) 
    };
    for (size_t i = 0; i < std::size(index_order);++i){ result[ index_order[i]] = i+1; }
    return result;
}();

排名存储在静态地图等级中,并且每个实例等级已经在施工时进行了评估(而不是在每个比较上,IE比较现在是便宜)。同样,该地图现在是从数组中生成的,该数组更强大(您不能再将索引/等级误认为)。此外,地图是 const ,即查找而不是 operator [] 用于查找。不在地图中的元素将分配等级0。实际上也是这样,但是在 operator [] 之前,可能会向地图添加不必要的元素。

You can wrap the type_index into a custom type with a comparator that yields the desired order.

The example from cppreference modified using std::map rather than std::unordered_map and with a custom comparator:

#include <iostream>
#include <typeinfo>
#include <typeindex>
#include <map>
#include <string>
#include <memory>
 
struct A {
    virtual ~A() {}
};
 
struct B : A {};
struct C : A {};

struct my_type_index {
    std::type_index index = std::type_index(typeid(void));
    my_type_index() = default;
    my_type_index(std::type_index i) : index(i) {}
    bool operator<(const my_type_index& other) const {
        static std::map< std::type_index,int> rank{
            { std::type_index(typeid(A)) , 1},
            { std::type_index(typeid(B)),  2},
            { std::type_index(typeid(double)),  3},
            { std::type_index(typeid(int)),  4},
            { std::type_index(typeid(C)),  5}
        };        
        return rank[index] < rank[other.index];
    }
};


int main()
{
    std::map<my_type_index, std::string> type_names;
 
    type_names[std::type_index(typeid(int))] = "int";
    type_names[std::type_index(typeid(double))] = "double";
    type_names[std::type_index(typeid(A))] = "A";
    type_names[std::type_index(typeid(B))] = "B";
    type_names[std::type_index(typeid(C))] = "C";
   
    for (const auto& e : type_names) {
        std::cout << e.first.index.name() << " " << e.second << "\n";
    }
}

output:

1A A
1B B
d double
i int
1C C

With improvements suggested by François Andrieux:

struct my_type_index {
    std::type_index index = std::type_index(typeid(void));
    int rank = 0;
    my_type_index() = default;
    my_type_index(std::type_index i) : index(i) {
        auto it = ranks.find(i);
        if (it != ranks.end()) rank = it->second;
    }
    
    static const std::map<std::type_index,int> ranks;
    
    bool operator<(const my_type_index& other) const {        
        return rank < other.rank;
    }
};

const std::map<std::type_index,int> my_type_index::ranks = [](){
    std::map<std::type_index,int> result;
    std::type_index index_order[] = {
        std::type_index(typeid(A)),
        std::type_index(typeid(B)),
        std::type_index(typeid(double)),
        std::type_index(typeid(int)),
        std::type_index(typeid(C)) 
    };
    for (size_t i = 0; i < std::size(index_order);++i){ result[ index_order[i]] = i+1; }
    return result;
}();

The ranking is stored in the static map ranks and each instances rank is already evaluated on construction (instead of on each comparison, ie comparisons are now cheaper). Also the map is now generated from an array, which is more robust (you cannot mistype the index/rank anymore). Further, the map is const, ie find instead of operator[] is used for look up. Elements not in the map will be assigned rank 0. Actually that was also the case before, but before operator[] was potentially adding unnecessary elements to the map.

自定义type_index订单无提升

不再让梦枯萎 2025-01-31 01:55:26

来自发行说明

OpenID连接注销

keycloak的先前版本支持自动注销
用户并通过打开注销端点URL将其重定向到应用程序
例如
http(s):// example-host/auth/auth/realms/my-realm-name/stoloption/openID-connect/logout?redirect_uri = encodedredirecturi。
尽管该实施易于使用,但它可能具有负面
对性能和安全性的影响。新版本有更好的支持
用于基于OpenID Connect RP启动注销的注销
规格。不再支持参数redirect_uri;
另外,在新版本中,用户需要确认注销。这是
可能省略确认并自动重定向到
当您包含参数POST_LOGOUT_REDIRECT_URI时应用程序
与参数ID_TOKEN_HINT一起使用的ID令牌
登录。

现有部署受到以下方式影响:

 如果您的应用程序直接使用redirect_uri参数登录端点的链接,则可能需要将其更改为
 

上面描述的。考虑删除redirect_uri参数
完全或用ID_TOKEN_HINT替换
POST_LOGOUT_REDIRECT_URI参数。

 如果您使用Java适配器,并且您的应用程序确实通过呼叫httpservletrequest.logout()注销,则不会受到影响,因为此调用
 

使用注销端点的后渠变体,一个是
没有更改。

 如果您使用最新的JavaScript适配器,则也不会受到影响。但是,如果您的应用程序使用旧版本的
 

JavaScript适配器,您会受到影响,因为此适配器使用了变体
使用已弃用的redirect_uri参数的注销端点。在
在这种情况下,您可能需要升级到最新版本的
JavaScript适配器。

 对于Node.js适配器,适用于JavaScript适配器的指南相同。鼓励您更新到最新版本
 

作为适配器的较旧版本,请使用不建议的redirect_uri
范围。使用最新的node.js适配器,您不会受到影响
只要您根据 /注销URL使用注销,如图所述
文档或node.js适配器示例中。但是,在
当您的应用程序直接使用该方法时
keycloak.logouturl,您可以考虑将idtokenhint添加为第二个
对此方法进行论点。将idtokenhint添加为第二的可能性
参数是在此版本中新添加的。 iDtokenhint需要
在登录过程中获得的有效ID令牌。添加
idtokenhint是可选的,但是如果您省略了,您的用户将需要
如前所述确认注销屏幕。他们也不会
注销后重定向回到应用程序。

有一个向后兼容的选项,该选项允许您
应用程序仍使用redirect_uri参数的旧格式。

您可以通过输入启动服务器时启用此参数
以下命令:

bin/kc。[sh | bat]
-spi-login-protocol-openid-connect-legacy-logout-redirect-uri = true start

使用此配置,您仍然可以使用该格式
redirect_uri参数。请注意,如果需要确认屏幕
省略ID_TOKEN_HINT。警告向后兼容性
开关将在以后的某些版本中删除 - 可能是KeyCloak 21。
鼓励您尽快更新客户
上面描述的而不是依靠此开关。

From the Release Notes:

OpenID Connect Logout

Previous versions of Keycloak had supported automatic logout of the
user and redirecting to the application by opening logout endpoint URL
such as
http(s)://example-host/auth/realms/my-realm-name/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri.
While that implementation was easy to use, it had potentially negative
impact on performance and security. The new version has better support
for logout based on the OpenID Connect RP-Initiated Logout
specification. The parameter redirect_uri is no longer supported;
also, in the new version, the user needs to confirm the logout. It is
possible to omit the confirmation and do automatic redirect to the
application when you include parameter post_logout_redirect_uri
together with the parameter id_token_hint with the ID Token used for
login.

The existing deployments are affected in the following ways:

If your application directly uses links to logout endpoint with the redirect_uri parameter, you may be required to change this as

described above. Consider either removing the redirect_uri parameter
entirely or replacing it with the id_token_hint and
post_logout_redirect_uri parameters.

If you use java adapters and your application does logout by call httpServletRequest.logout(), you are not affected because this call

uses the backchannel variant of the logout endpoint and that one was
not changed.

If you use the latest javascript adapter, you are also not affected. However if your application uses an older version of the

JavaScript adapter, you are affected as this adapter uses the variant
of the logout endpoint with the deprecated redirect_uri parameter. In
this case, you may need to upgrade to the latest version of the
JavaScript adapter.

For the Node.js adapter, the same guideline applies as for the JavaScript adapter. You are encouraged to update to the latest version

as the older version of the adapter uses the deprecated redirect_uri
parameter. With the latest Node.js adapter, you are not affected as
long as you use the logout based on the /logout URL as described in
the documentation or in the Node.js adapter example. However, in the
case when your application directly uses the method
keycloak.logoutUrl, you can consider adding idTokenHint as the second
argument to this method. The possibility to add idTokenHint as second
argument was newly added in this version. The idTokenHint needs to be
a valid ID Token that was obtained during the login. Adding
idTokenHint is optional, but if you omit it, your users will need to
confirm the logout screen as described earlier. Also they will not be
redirected back to the application after logout.

There is a backwards compatibility option, which allows your
application to still use the old format of the redirect_uri parameter.

You can enable this parameter when you start the server by entering
the following command:

bin/kc.[sh|bat]
--spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true start

With this configuration, you can still use the format with the
redirect_uri parameter. Note the confirmation screen will be needed if
the id_token_hint is omitted. Warning The backwards compatibility
switch will be removed in some future version - probably Keycloak 21.
You are encouraged to update your clients as soon as possible as
described above rather than rely on this switch.

KEYCLOAK:使用React用户可以登录,但是当我尝试注销时,我会收到消息“无效参数:redirect_uri”

不再让梦枯萎 2025-01-30 20:27:17

中重新编写您的代码

if (dataSnapshot.value != null) {
  dataSnapshot.value.forEach((key, value){ //Error highlights the forEach here.
  Post post = createPost(value);
  post.setId(dataReference.child('posts/' + key));
  posts.add(post);
});

您只需要从: }

...
if (dataSnapshot.value != null) {
  for(var entries in dataSnap.value){
      Post post = createPost(entries.value);
      post.setId(dataReference.child('posts/' + entries.key));
      posts.add(post);
  }
}
...

这是

You simply need to re-write your code from:

if (dataSnapshot.value != null) {
  dataSnapshot.value.forEach((key, value){ //Error highlights the forEach here.
  Post post = createPost(value);
  post.setId(dataReference.child('posts/' + key));
  posts.add(post);
});

}

into this:

...
if (dataSnapshot.value != null) {
  for(var entries in dataSnap.value){
      Post post = createPost(entries.value);
      post.setId(dataReference.child('posts/' + entries.key));
      posts.add(post);
  }
}
...

This is documented online in the dart-lang linter.

方法&#x27; foreach&#x27;可以无条件地调用,因为接收器可以是null&#x27;

不再让梦枯萎 2025-01-30 12:09:03

我通过读取文件中的所有内容并附加我想写入文件的JSON对象,然后一次写入所有内容,然后立即编写所有内容,从而解决了这个问题。

I solved this problem by reading all of the content in the file and appending the JSON object that I wanted to write to the file and then write it all at once.

如何在Java中编写JSON对象之前删除卷曲括号

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

更多

友情链接

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文