考虑以下代码片段:
require "sqlite3"
db = SQLite3::Database.new "my.db"
p db.execute("select * from user where name = ?", ["my_user_name"])
这将输出数据库中用户名为“my_user_name”的条目。这按预期工作。
现在考虑这个代码片段(config.ru):
require "rack/auth/basic"
require "sqlite3"
use Rack::Auth::Basic, "my authentication" do |username, password|
p username
p db.execute("select * from user where name = ?", [username])
end
run do |env|
[200, {}, []]
end
当我向该服务器发送请求时:
curl -X POST -v -ujomy:abc123 localhost:9292 -d ''
我在启动服务器的终端中看到以下输出(使用rackup):
"my_user_name"
[]
所以我现在没有从我的 sql 查询中得到结果。
当我在 db.execute 语句之前插入此行时:
username = "my_user_name"
现在我真的得到了结果。
用
username
替换 username.to_s
也不起作用。
那么看来使用Rack提供的用户名变量不适用于sqlite?这怎么可能,因为
username.class
是String
? username.size
也等于 "my_user_name".size
。
这是一个编码问题。在此块中
username
和 password
被编码为“ASCII-8BIT”。
use Rack::Auth::Basic, "my authentication" do |username, password|
p username
p db.execute("select * from user where name = ?", [username])
end
要解决此问题,您可以使用
String#force_encoding
更改编码,如下所示:
use Rack::Auth::Basic, "my authentication" do |username, password|
p username
p db.execute("select * from user where name = ?", [username.force_encoding('UTF-8')])
end