ورود

View Full Version : مشکل در استفاده از ajax



volkswagen
جمعه 25 تیر 1400, 21:57 عصر
سلام ، من از کد زیر برای ارسال درخواست ajax در یک فایل blade.php استفاده کردم:


<body>
<button type="button" onclick="loadDoc()">Request data</button>

<span id="err">error</span>
<head>

<script>
function loadDoc() {
var response;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// document.getElementById("demo").innerHTML = this.responseText;

console.log(response.success);

}
};
xhttp.open("GET", "rout5", true);
xhttp.send();

}
</script>
</head>
</body>


کنترلر:


public function AjaxController(){

return response()->json(['success' => 'hello world']);
}





روت:

Route::get('rout5',[AjaxController::class,'AjaxController']);




موقع اجرا برنامه ، در تب network مقدار 200 رو دریافت می کنم ولی در تب console ، ارور response not definde رو دریافت می کنم ، مشکل از چیه ؟ چجوری باید response رو تعریف کنم که اونو بشناسه ؟ تشکر

plague
دوشنبه 28 تیر 1400, 12:14 عصر
از jquery استفاده کن بجای javascript خام خیلی ساده تره من از js [ام هیچوقت استفاده نکردم ولی با یه نگاه به نمونه های آنلاین
پاسخ برگشتی توی this.responseText هستش و اگر جیسون برگشت میده سمت php باید سمت js دیکدش کنی اول



var ajax_response = JSON.parse(this.responseText);
console.log(ajax_response.success);

volkswagen
دوشنبه 28 تیر 1400, 15:08 عصر
بسیار ممنون....مشکل ام حل شد.
jquery بلد نیستم و البته داره منسوخ میشه و باید رفت سمت فریم ورک های جدید...

برای این داستان هم هر چی سرچ کردم ، با jquery بود و متاسفانه ازش سردرنمیارم

volkswagen
دوشنبه 28 تیر 1400, 16:27 عصر
از jquery استفاده کن بجای javascript خام خیلی ساده تره من از js [ام هیچوقت استفاده نکردم ولی با یه نگاه به نمونه های آنلاین
پاسخ برگشتی توی this.responseText هستش و اگر جیسون برگشت میده سمت php باید سمت js دیکدش کنی اول



var ajax_response = JSON.parse(this.responseText);
console.log(ajax_response.success);


اگر منبعی با استفاده از jquery سراغ دارید ، بذارید ممنون می شم

plague
سه شنبه 29 تیر 1400, 11:22 صبح
جی کوئری خیلی سادست و عمق زیادی نداره می ارزه یاد گرفتنش
خیلی فریم ورک های دیگه از جی کوئری استفاده میکنن مثل بوت استرپ و انقد گستردست استفاده ازش که منسوخ نمیشه به این زودی ها
فیلم های آموزشیش زیاد هست اگه زبانت خوب باشه

volkswagen
سه شنبه 29 تیر 1400, 18:06 عصر
--------------

volkswagen
سه شنبه 29 تیر 1400, 18:07 عصر
اکی مرسی ؛ ی سوال دیگه هم داشتم و اون اینکه اگر بخوام موقع ارسال درخواست ، کوئری استرینگ هم ارسال کنم ، چنین چیزی صحیح هست؟





var id=1;
xhttp.open("GET", "rout5/{id}", true);






route:


Route::get('/rout5/{id}',[AjaxController::class,'AjaxController']);



همچنین ، برای گرفتن درخواست از سرور ، در کنترلر اینو نوشتم:



return response()->json(['success' => 'hello world']);


حالا اگر به صورت آرایه ارسال اش کنم:


$test = array("1", "2", "3");
return response()->json([$test]);



در فایل blade ، چجوری باید دریافت اش کنم؟ چیو باید fetch کنم ؟ تشکر

اینطوری؟



let result=ajax_response.success;
result.forEach(s =>console.log(s));

volkswagen
سه شنبه 29 تیر 1400, 19:38 عصر
البته فکر کنم برای ارسال درخواست بهمراه کوءری استرینگ ،باید از این روش استفاده کرد:



var url="rout5/" + 1;
xhttp.open("GET", url, true);

volkswagen
چهارشنبه 30 تیر 1400, 04:51 صبح
کدها مثال هست .در مثال زیر دو تا list box داریم که به ازای انتخاب آیتم از یکی از لیست ها ، درخواست به وسیله ajax ارسال میشه و میره از دیتابیس اطلاعات مورد نظر رو میاره و در list box دوم نمایش میده








<body>

<span id="err">error</span>
<head>

<script>
function loadDoc() {
var response;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {

var ajax_response = JSON.parse(this.responseText);
var result=ajax_response.success
//console.log(person.firstName) ;
//console.log(result.subcategory_en) ;

result.forEach(myFunction);
function myFunction(item, index) {
console.log(item. subcategory_fa ) ;
var x = document.getElementById("mySelect");
var option = document.createElement("option");
option.text = item.subcategory_en + "|" + item. subcategory_fa;

x.add(option);

}

};

};

var x = document.getElementById("category_test").selectedIndex;

var e = document.getElementById("category_test");
var Selec_id = e.options[e.selectedIndex].value;

//console.log(Selec_id);

var url="rout5/" + Selec_id;
//xhttp.responseType="json";

xhttp.open("GET", url, true);
xhttp.send();

}
</script>


</head>
</body>

volkswagen
چهارشنبه 30 تیر 1400, 04:56 صبح
در نهایت فکر کنم به این صورت باید اطلاعات رو fetch کرد(البته کدها رو برای مثال نوشتم و در نهایت باید ویرایش بشه تا کار کنه)



var person = {
firstName: "John",
lastName: "Doe",
age: 50,
eyeColor: "blue"
};


var result=ajax_response.success
result.forEach(myFunction);
function myFunction(item, index) {
console.log(item.firstName)

plague
چهارشنبه 30 تیر 1400, 13:38 عصر
به راوت هات باید نام بدی و از نامشون توی سیستم استفاده کنی اینجوری بعدا اگه خواستی لینک رو تغییر بدی نیاز ینست قالب رو دست بزنی


Route::get('/rout5',[AjaxController::class,'AjaxController'])->name('someroute');

البته اگه پارامتر های ارسالیت رو با javascript بدست میاری و نمیتونی تو راوت php بزاری بهتره با کوئری استرینگ یا post ارسال کنی و جزوی از راوت نزاریشون

جیکوئری سادست با

$(selector)

المنت ها رو انتخاب میکنی که سلکتورش مثل css هستش مثلا اگه المنتی با آیدی category_test رو بخای میشه


$('#category_test')

بعد که انتخابش کردی میگی حالا چیکارش کن مثلا اگه value رو بخای

$('#category_test').val();

90% جی کوئری همینه ارسال ایجکس هم با جی کوئری به این شکله

$.get( 'address' , { query_String_key : query_string_value}, function(result){

// result -> pasokh bargashti

});



یعنی کلش میشه


function loadDoc()
{
var category_id = $('#category_test').val();
$.get( '{{route('someroute')}}' , { category_id : category_id}, function(ajax_response){

var ajax_response = JSON.parse(ajax_response);
});
}




این خط ممکنه اررور بده

var ajax_response = JSON.parse(ajax_response);


چون جیکوئری اگه درست درخواستت رو برگشت بدی خودش دیکد میکنه جیسون رو و نیازی نیست دیگه به این خط چون داری چیزی که قبلا دیکد شده اتومات رو دوباره دیکد میکنی

در مورد آرایه هم جاواسکریپت 2 نوع آرایه داره که شکلشون فرق میکنه
آرایه با کلید که بهش آبجکت میگن و به این شکله

var data = { k : v , k : v }

آرایه بدون کلید که به این شکله


var data = [ v , v, v ];

برای خوندنشون باید بسته به اینکه کدوم مدل رو داری حلقه بزاری

var data = ['a' , 'b' , 'c'];
data.forEach((element) => {
console.log(element);
});

نوع با کلید

var data = { name : 'ali' , last_name : 'alavi'};
for (var [key, value] of Object.entries(data)) {
console.log(key, '->' , value);
}

که نوع با کلید رومعمولا توی حلقه نمیزارن چون کلید داره و مستقیم بهش دسترسی پیدا میکنن


var data = { name : 'ali' , last_name : 'alavi'};

console.log(data.name);
console.log(data.last_name);



باید دید کد php چجوری پاسخ رو برگشت میده مثلا اگه همچین چیزی داشته باشی توی کنترلرت برای گرفتن زیر دسته ها



function get_subcategories(Request $request ){

$categories = Category::where( 'parent_id' , $request->input('category_id) )->get();
return response()->json(['success' => 1 , 'categories' =>$categories]);

}


توی ajax_response این رو خواهی داشت



{
success : 1 ,
categories : [ { id : 1 , title : 'a' } , { id : 2 , title : 'b' } , { id : 3 , title : 'c' } ]
}





ترکیبی از آرایه با کلید و بدون کلید


باید اینجوری هندلش کنی





for (var [key, value] of Object.entries(ajax_reponse.categories)) {
console.log(value.id , value.title);
}



کلش میشه


function loadDoc()
{
var category_id = $('#category_test').val();
$.get( '{{route('someroute')}}' , { category_id : category_id}, function(ajax_response){

var ajax_response = JSON.parse(ajax_response);

if(ajax_response.success == 1 )
{
for (var [key, value] of Object.entries(ajax_reponse.categories)) {
console.log(value.id , value.title);
}
}
else
{
alert('something went wrong ! ');
}


});
}

volkswagen
چهارشنبه 30 تیر 1400, 22:56 عصر
مرسی از توضیحات کامل...
من در نهایت با خود جاوا اسکریپت نوشتم ولی ظاهرا با jquey خیلی راحت تره...دلیل اش هم اینه که میخوام در آینده از vue.js در کنار لاراول استفاده کنم تا با axios اینکارو بکنم ک البته فعلا حوصله اش نبود.



این خط ممکنه ارور بده:


var ajax_response = JSON.parse(ajax_response);




بله اشتباهی نوشتم ، در کدهای برنامه ام ، اینطوری نوشتم:



var ajax_response = JSON.parse(this.responseText);
var result=ajax_response.success


فقط من نفهمیدم که اگر قراره json رو به آرایه ای از object ها تبدیل کنیم ، چرا اینطوری نمی نویسیم؟



var ajax_response = JSON.parse(this.responseText.success);

و میایم اینطوری می نویسیم:



var ajax_response = JSON.parse(this.responseText);






کوءری استرینگ درست بود که نوشتم؟ چون برای من جواب میده



var Selec_id = 1;
var url="rout5/" + Selec_id;
xhttp.open("GET", url, true);

plague
پنج شنبه 31 تیر 1400, 12:38 عصر
جیسون یک استاندارد هست برای تبدیل ساختار های پیچیده مثل آرایه به رشته و برگشت اون رشته به آرایه
آرایه در زبان های مختلف ساختار متفاوتی داره و شما نمیتونی یک آرایه php رو به js بدی چون آرایه در js شکل متفاوتی داره و قابل درک نیست براش آرایه php (دلیل های دیگری هم داره که بهش وارد نمیشم )

ولی هردو رشته جیسون رو میفهمن پس وقتی بخای یک آرایه رو از php بدی به js اول جیسون کد میکنی تبدیل به رشته جیسون بعد رشته رو به js پاس میدی و اونجا دیکد میکنه برمیگردونه به آرایه

مثل اینه که یه ایرانی بخاد با یک چینی صحبت کنه ... زبان همدیگه رو بلد نیستن ولی هردو انگلیسی بلدن
پس چیزی که میخای بگی رو تبدیل میکنی به انگلیسی و به طرف میگی و اون طرف هم انگلیسی رو ترجمه میکنه به زبون خودش و متوجه میشه شما چی گفتی



responseText پاسخ برگشتی از کنترلر هستش که یک رشته جیسونه و طبیعتا شما باید رشته جیسون رو دیکد کنی تا برگرده به آرایه
responseText.success یه خونه هست توی آرایه responseText و تا وقتی responseText رو دیکد نکنی تا تبدیل بشه به آرایه اصلا نمیتونی بهش دسترسی داشته باشی
و وقتی هم دیکد کنی responseText رو دیگه جیسونی در کار نیست و یه آرایه برات میمونه

مثل اینه که شما یک جعبه داری که توش یه سری آیتم هستن مثلا لیوان یا سیب یا هرچی
شما باید اول جعبه رو باز کنی تا به آیتم های توش دسترسی داشته باشی
این حرف شما اینه که بخای بدون باز کردن جعبه یک آیتم درونش رو باز کنی ... اول اینکه تا وقتی جعبه رو باز نکردی به آیتم های توش دسترسی نداری دوم اینکه آیتم های درونش (مثلا لیوان) باز شدنی نیستن



var url="rout5/" + Selec_id;


این جواب میده ولی روش خوبی نیست
بهتره از نام راوت استفاده کنی بجای آدرسش




Route::get('/rout5',[AjaxController::class,'AjaxController'])->name('someroute');


توی js


var url="{{route('someroute')}}?id=" + Selec_id;

که سیستم بره تو فایل راوت چک میکنه کدوم راوت این نام رو داره و میاد اینجا میزاره


دلیلش اینه که اگه از آدرس راوت استفاده کنی و بعدا بخای آدرس رو عوض کنی مثلا بجای rout5 بخای بزاری rout6 اونقت باید بری توی قالب هات یا هرجای دیگری این راوت استفاده شده بری همه رو تغییر بدی

ولی اگه از نامش استفاده کنی توی قالبت یا کد های js نیازی نیست چیزی رو تغییر بدی حتی اگه آدرسش عوض بشه چون شما نامش رو قید کردی و نه آدرس رو که بخای تغییری بدی ... یعنی کافیه توی فایل راوت آدرس رو تغییر بدی فقط

volkswagen
پنج شنبه 31 تیر 1400, 18:21 عصر
مرسی از توضیحات کامل و جامع

volkswagen
جمعه 01 مرداد 1400, 22:15 عصر
این جواب میده ولی روش خوبی نیست
بهتره از نام راوت استفاده کنی بجای آدرسش





1
Route::get('/rout5',[AjaxController::class,'AjaxController'])->name('someroute');







توی js




1
var url="{{route('someroute')}}?id=" + Selec_id;







احتمالا نحوه تعریف کردن روت ، خطای املایی نداره ؟ چون وقتی از این روش استفاده می کنم ؛ بهم ارور میده:



Missing required parameter for [Route: someroute] [URI: rout6/{id}] [Missing parameter: id]



بعد از آدرس ، فکر کنم باید رشته ارسالی هم نوشته بشه ، یعنی اینطوری:


Route::get('/rout5/{id}',[AjaxController::class,'AjaxController'])->name('someroute');

plague
شنبه 02 مرداد 1400, 11:46 صبح
از اونجایی که نمیتونی از js متغیر به php پاس بدی (چون اول کد های php توی سرور احرا میشه و بعدا کد های js توی مرورگر اجرا میشه )
نباید پارامتر رو توی لینک بزاری .... باید کوئری استرینگ پارامتر رو بزاری

راوت رو بزار



Route::get('/rout5',[AjaxController::class,'AjaxController'])->name('someroute');


اینجوری آدرس بده بعدش


var url="{{route('someroute')}}?id=" + Selec_id;


اینجور یتابع رو توی کنترلر بنویس و دریاف کن


function AjaxController(Request $request){

$request->input('id'); // hamon $_GET['id'] mishe

}

اگه بخای توی لینک بزاری پارامتر رو باید لینک رو یجایی توی صفحه ذخیره کنی و از اون بخونی
مثلا توی دکمه



<a href="#" id="doc-btn" data-id="{{route('someroute' , ['id'=> 5 ])}}" onclick="loadDoc()"> click me </a>

و بعد اینجوری توی تابع بخونیش



function loadDoc(){

var btn = document.getElementById('doc-btn');
var url = btn.getAttribute('data-id');

}

volkswagen
شنبه 02 مرداد 1400, 22:36 عصر
مشکل حل شد ، ممنون