在我的 Laravel 10 测试项目中,我遇到了从存储文件夹读取 JSON 文件并作为简单文本输出到浏览器中的问题。
如果 JSON 中存在带有转义 HTML 代码的字符串字段 和/或 转义序列,其中一些在浏览器中打印为真正的换行符/换行符。
我创建了一个可重现的示例。
假设我有一个文本 JSON 文件,此对象作为内容:
{"html":"<!DOCTYPE html>\n<html><head><meta charset=\"UTF-8\"><\/head><body>\n<p style=\"vertical-align:middle;font-size:2em;\" >\ntest\n<\/p><\/body><\/html>"}
HTMl 来自文本编辑器,因此它可以包含 和/或 转义序列。
如果我将文件放入公共文件夹并要求浏览器通过其 url 检索其内容,我会得到以下输出:
{"html":"<!DOCTYPE html>\n<html><head><meta charset=\"UTF-8\"><\/head><body>\n<p style=\"vertical-align:middle;font-size:2em;\" >\ntest\n<\/p><\/body><\/html>"}
这是正确的。
如果我将文件放在存储的合适文件夹中并在 web.php 文件中应用此路由:
Route::get('/demo/{filename}', function ($filename) {
$filePath =Storage::path("public/demo/".$filename);
\Log::Info('file '.$filePath);
if (file_exists($filePath)) {
$json = file_get_contents($filePath);
\Log::Info($json);
return $json; //the same if the echo function is used
} else {
return view('welcome'); }
});
然后要求浏览器检索文件,我得到以下输出:
{"html":"\n<\/head>\n
\ntest\n<\/p><\/body><\/html>"}
可以看到是三行,中间有一条线,缺少零件。最后一行的字体也更大,虽然在这里看不到。
(在示例代码中你可以使用echo函数代替return语句,得到相同的结果)
日志文件中的不同输出:
[2024-03-26 12:25:29] production.INFO: {"html":"<!DOCTYPE html>
<html><head><meta charset=\"UTF-8\"><\/head><body>
<p style=\"vertical-align:middle;font-size:2em;\" >
test
<\/p><\/body><\/html>"}
如您所见,也有新线路。主要区别在于它不像在浏览器中那样呈现为 HTML,但输出是相同的。
这个问题是我的代码的错误还是 Laravel 的错误?可以解决吗?
您将返回原始的未解析的 JSON 作为常规响应,该响应将被解释为 HTML,并且其中的任何标签都将被解释。
您可以手动告诉浏览器您要返回 JSON:
return response($json)->header('Content-Type', 'application/json');
或者解析 JSON 并返回 JSON 响应:
$json = json_decode($json);
return response()->json($json);