英文:
When using Laravel I can't get an ajax call to pass data to a class method
问题
我很新于Laravel。
我想要从一个ajax调用中传递两个变量到类中的一个方法。
我的ajax调用(来源于各种Google搜索)如下:
var token = $('meta[name="csrf-token"]').attr('content');
var inputValue = "Testing";
var anotherInput = "Testing2";
var data = {};
data.anotherInput = anotherInput;
data.inputValue = inputValue;
data._method = 'POST';
data._token = token;
$.ajax({
url: postUrl,
type: 'POST',
headers: {
'X-CSRF-TOKEN': token
},
data: JSON.stringify(data),
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
processData: false,
success: function (response) {
console.log(response);
},
error: function (response) {
console.log(response);
}
});
变量"postUrl" 在我的 layout.blade.php 中设置如下:
<script>
var postUrl = "{{ route('filepathtest') }}";
</script>
我的控制器类顶部如下:
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use Illuminate\Http\Response;
use App\Models\MainSettings;
use App\Http\Requests\MainSettingsRequest;
class MainSettingsController extends Controller
{
private string $messageTitle = "";
private $messageText = array();
/**
* 修正路径并检查是否指向某个东西。
*/
public function filePathTest(Request $request)
{
$data = $request->all();
$response = array(
'msg' => $data,
);
return response()->json($response);
}
}
最后,我的路由如下:
Route::match(array('GET','POST'),'filepathtest', [MainSettingsController::class, 'filePathTest'])->name('filepathtest');
我的响应被记录到Console.Log中,我看到这个:
我尝试了很多种从控制器中访问变量的方法,但都没有成功?
我尝试过:
$data = $request->input('anotherInput');
和:
$data = $request->anotherInput;
和:
$data = $request['anotherInput'];
和:
$data = $request->post('anotherInput');
和:
$data = $request->request('anotherInput');
但它们似乎都返回null,除了最后一个会给我一个错误(除非我在顶部只使用"use Request;"而不是"use Illuminate\Http\Request;")?
英文:
I'm very new to Laravel.
I would like to pass two variables from an ajax call to a method within a class.
My ajax call (derived from various Google searches) is:
var token = $('meta[name="csrf-token"]').attr('content');
var inputValue = "Testing";
var anotherInput = "Testing2";
var data = {};
data.anotherInput = anotherInput;
data.inputValue = inputValue;
data._method = 'POST';
data._token = token;
//data: JSON.stringify(data),
$.ajax({
url: postUrl,
type: 'POST',
headers: {
'X-CSRF-TOKEN': token
},
data: JSON.stringify(data),
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
processData: false,
success:function(response)
{
console.log(response);
},
error: function(response) {
console.log(response);
}
});
The var "postUrl" is set in my layout.blade.php here:
<script>
var postUrl = "{{ route('filepathtest') }}";
</script>
The top of my Controller Class is:
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
// use Request;
use Illuminate\Support\Facades\Input;
use Illuminate\Http\Response;
use App\Models\MainSettings;
use App\Http\Requests\MainSettingsRequest;
class MainSettingsController extends Controller
{
private string $messageTitle = "";
private $messageText = array();
/**
* Corrects path and checks it points to something.
*/
public function filePathTest(Request $request)
{
$data = $request->all();
$response = array(
'msg' => $data,
);
return response()->json($response);
}
And, finally, my route is:
Route::match(array('GET','POST'),'filepathtest', [MainSettingsController::class, 'filePathTest'])->name('filepathtest');
My response gets logged to Console.Log and I see this:
I've tried lots of ways of accessing the variables from the Controller but to no avail?
I've tried:
$data = $request->input('anotherInput');
And:
$data = $request->anotherInput;
And:
$data = $request['anotherInput'];
And:
$data = $request->post('anotherInput');
And:
$data = $request->request('anotherInput');
But they all seem to return null apart from the last one gives me an error (unless I just "use Request;" at the top instead of "use Illuminate\Http\Request;") ?
答案1
得分: 3
这似乎是有关你的 $.ajax()
请求的一些因素的组合。至少对于 POST
请求,以下内容应该有效:
$.ajax({
type: 'POST', // 或 'PATCH'、'DELETE' 等。
url: postUrl, // 可以是来自 Laravel 路由或其他外部 URL 的有效 URL。
data: postData // 任何纯粹的 JS 对象或 `FormData` 等。
// ...
});
在这种情况下,存在一些问题:
data: JSON.stringify(data)
在这种情况下,你将你的 data
对象编码为一个字符串,然后将其发送到控制器。当通过 \Log::info($request->all());
记录时,$request->all()
将该 JSON 字符串用作数组索引,因此出现了奇怪的输出 ['{"anotherInput":"Testing2", ...}' => null]
。
这应该简单地是 data: data
,甚至可以使用 JS 对象的简写形式,只写成 data
。
processData: false
我不太熟悉这个设置,但你可以查看 $.ajax()
文档以了解何时适合使用它:https://api.jquery.com/jquery.ajax/
dataType
、contentType
和headers
在这里本质上没有问题,但请检查在进行 AJAX
请求时是否真的需要这些。如果你的数据中包括 _input
键,你可能可以省略 headers
,但发送两次可能也不会有害。
总之,当重构为以下代码时,你的代码应该能够正常工作:
$.ajax({
data: {
inputValue: 'Testing',
anotherInput: 'Testing2',
'_method': 'POST',
'_token': $('meta[name="csrf-token"]').attr('content'),
},
type: 'POST',
url: postUrl,
success: function(response) {
console.log(response);
},
error: function(response) {
console.log(response);
}
});
在后端,$request->all()
应该返回一个基于发送的数据的 4 个索引的数组,而 $request->input(...)
应该返回其中任何一个索引的值,如果指定无效的索引,则返回 null
。
英文:
So this seems to be a combination of factors of your $.ajax()
request. At a minimum, this should work for POST
requests:
$.ajax({
type: 'POST', // or 'PATCH', 'DELETE', etc.
url: postUrl, // Any valid URL from your Laravel Routes or other external URL
data: postData // Any plain JS object, or `FormData`, etc.
// ...
});
In this case, there were a few issues:
data: JSON.stringify(data)
In this case, you were encoding your data
object as a single String, and sending that to the controller. $request->all()
was using that JSON string as an Array index, hence the weird ['{"anotherInput":"Testing2", ...}' => null]
output when logging via \Log::info($request->all());
This should simply be data: data
, or even just data
using JS object shorthand.
processData: false
I'm not familiar with this setting, but you can review the $.ajax()
documentation to see when it is appropriate to use this: https://api.jquery.com/jquery.ajax/
dataType
,contentType
andheaders
There wasn't anything wrong here per-se, but review if these are actually needed when making the AJAX
request. If the _input
key is included in your data, you can probably omit headers
, but I doubt it would hurt to send it twice.
So, all in all, your code should function when refactored to:
$.ajax({
data: {
inputValue: 'Testing',
anotherInput: 'Testing2',
'_method': 'POST',
'_token': $('meta[name="csrf-token"]').attr('content'),
},
type: 'POST',
url: postUrl,
success: function(response) {
console.log(response);
},
error: function(response) {
console.log(response);
}
});
On the backend, $request->all()
should return an array with 4 indices based on the data sent, and $request->input(...)
should return the value of any of those indices, or null
if specifying an invalid index.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论