making an Ajax request to a Yii Controller method from a Javascript function

Hi,

I am very stuck trying to make an ajax request to a php file.

I’ve tried several methods of request

Here’s one in a script function which is called after user clicks a button


  $.ajax({ 

                      url: '<?php echo Yii::$app->request->baseUrl.'filename.php'?>',

                      data: {name: properties.filename},

                      type: "POST",

                      success: function(){

                          console.log("success");

                      },

                      error: function(){

                          console.log("failure");

                      }

                });

The problem with this request was that no functionality in filename.php is executed. It seems like the file is being skipped entirely.

I’ve also tried


  $.ajax({ 

                      url: '<?php echo Yii::$app->request->baseUrl.'controller/action'?>',

                      data: {name: properties.filename},

                      type: "POST",

                      success: function(){

                          console.log("success");

                      },

                      error: function(){

                          console.log("failure");

                      }

                });

This request brings be to the baseURL which is the localhost/web folder in Yii, and is not where the controller files are.

In fact, I am unable to direct the request to a file anywhere other than the baseURL. Even when I take the baseURL out it automatically inserts it in for me when the request is made.

The ideal solution would be to get the ajax request to call a Yii controller.

Any help is appreciated! Thank you.

If you supply the controller code and the filename.php code I might be able to help.

Here’s the little of what I have for the controller code in a file called FileController.php

The controller is saved in the file directory basic/controllers




	public function actionLog(){


		if(Yii::$app->request->isAjax){

			$data= Yii::$app->request->post();

		} 


		

	}



And here is the code for filename.php


<?php


namespace app\controllers;


use Yii;

use app\models\History;


if(isset($_POST['name']) && !empty($_POST['name'])) {




	$file_name = $_POST['name'];

	

	$log = new History();

	$log->name = $file_name;

	$log->save();

}


?>

It’s just a trial run to connect to the history table in my database and add a new row, but nothing is happening when the request is made.

Thanks for your help

I think it might just be a matter of sending the request to the correct URL, which I cannot seem to do.

Is this your first attempt at a yii program ? I only ask because it looks like at first glace that your not understanding the flow of Yii2 just yet.

Where is filename.php located?

EDIT: Also can you paste where you are doing the routing in @app/config/web.php or where ever your config file is.

Yea, I am still trying to get a grasp of how yii works.

filename.php is located in baseURL, which is localhost/basic/web

Here’s the URL setting in config/web.php

$config = [

'id' =&gt; 'basic',


'basePath' =&gt; dirname(__DIR__), ....

]

I am not sure if this is what you’re looking for.

Well you probably need to do a little reading then.

I have not read this article, but this is the sort of content you want to look for. MVC or Model View Controller topics relating to Yii2. There is a few out there for Yii, and its good for getting the idea, but you really want your head in Yii2 now, not Yii 1.*.

Try this article out for a start.

Now to your problem.

I would recommend using everything out the box until you understand how it all works.

So stick with the SiteController do not change it to FileController

Now to start off with in @app/config/web.php

Add this in there, it is used for simplifying urls so youdomain.com/index.html will goto your index action, simple. Also a bit of setup for using /gii also, you might want that later so i left it in.

More information here: http://www.bsourcecode.com/yiiframework2/url-manager-in-yiiframework-2-0/#configure-url-rules


$config = [

	... , // Do not include this .. its to show other content might be here.

	'components' => [

		... ,  // Do not include this

		'urlManager' => [

			'enablePrettyUrl' => true,

			'showScriptName' => false,

			'enableStrictParsing' => false,

   			'suffix' => '.html',

			//'cache' => 'cache',

			//'scriptUrl' => '',

			'baseUrl' => '/',

			//'hostInfo' => 'http://www.yourhost.com.au',

			'routeParam' => 'r',

			'ruleConfig' => [

				'class' => 'yii\web\UrlRule'

			],

			'rules' => array(

				[

					'pattern' => 'gii',

					'suffix' => '',

					'route' => 'gii',

				],

				[

					'pattern' => '/<controller:\w+>',

					'suffix' => '',

					'route' => 'gii/<controller>',

				],

				[

					'pattern' => '/<controller:\w+>/<action:\w+>',

					'suffix' => '',

					'route' => 'gii/<controller>/<action>',

				],

				'' => 'site/index',

				[

					'pattern' => '<action:\w+>',

					'suffix' => '.html',

					'route' => 'site/<action>',

				],

				

			),

		],

		... , // Do not include this

	]

];



Secondly you need to add a .htaccess file to @web/.htaccess

This is so all requests get redirected to your index.php file again so Yii2 can look at the query you made.


<IfModule mod_rewrite.c>

RewriteEngine on


RewriteBase /


RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d 

RewriteRule . /index.php$1 [L,NC]


</IfModule>

Now for @app/controllers/SiteController.php

In this file you basically had what you needed, but I am including more options for you to play with.

So add the following maybe below the actionIndex() function.

Also check out http://www.yiiframework.com/doc-2.0/guide-runtime-responses.html




	public function actionLog()

	{

		if (Yii::$app->request->isAjax) {

			$data = Yii::$app->request->post();

			$filename = $data['name'];

			

			//$log = new History();

			//$log->name = $filename;

			//$log->save();

		

			$response = Yii::$app->response;

			$response->format = \yii\web\Response::FORMAT_JSON;

			$response->data = ['filename' => $filename];

			$response->statusCode = 200;

			return $response;

		}

		else throw new \yii\web\BadRequestHttpException;

	}

And finally in a view file, I am using the index file @app/views/site/index.php

Add this anywhere in the file, it is just a simple ajax link.


	<?php 

	use yii\helpers\Html;

	use yii\helpers\Url;

	echo Html::a('Ajax Link Label','#', [

		'title' => 'Ajax Title',

			'onclick'=>"

			 $.ajax({

			type     :'POST',

			cache    : false,

			data: {name: 'myfilename'},

			url  : '".Url::to(['site/log'])."',

			success  : function(response) {

				console.log('success: '+response.filename);

			},

			error: function(){

			  console.log('failure');

			}

			});return false;",

	]);

	?>

Now when you goto yourdomain/index.html and click that link you will get a response in the console of "success: myfilename".

But if you went to yourdomain/log.html you will notice you get a "Bad Request (#400)" error because you are trying to access the log action directly and not via ajax. That is because we throw that exception in the log action.

[i]

NOTE: Now just as a disclaimer, I would not be making any important changes to databases or the like based on an ajax call. This is client side stuff so you need to make sure the controller action is protected from any sort of injection.[/i]

I hope that is all clear enough for you,

Noddy.