Joomlaのカスタムコンポーネントを開発しています! 3.xでAJAXを呼び出してデータを取得する場合。適切な方法は何ですか?
この回答はすでに数年前のものであり、更新されていないことに注意してください。正確ではないと思われる場合は、自由に編集/コメントしてください。
これに対処するための実際に公式な方法はほとんどありません。それは、複雑さと、MVCパターンに依存して作業をどの程度行うかによって大きく異なります。
以下は、Joomla 2.5および3.xで機能する可能性のあるいくつかの解決策です。コードはコピー-貼り付けジョブではなく、一般的なアイデアとして提示されています。
Joomlaの前に! 3.2以下の例を使用するために必要なのはcomponent
だけです。 Joomla 3.2(より複雑なタスク用)以降では、モジュールとプラグインからのリクエストを処理できます。
タスクの[〜#〜] url [〜#〜]は次のようにする必要があります。
_index.php?option=com_similar&task=abc&format=raw
_
次に、ビューを使用するコントローラーを作成します。たとえば、view.raw.htmlファイル(通常のビューファイルと同じ)を含むAbc
としましょう。
以下は、生のHTML応答を生成するためのコードです。
/ controller.php
_public function abc()
{
// Set view
// Joomla 2.5
JRequest::setVar('view', 'Abc');
// (use JInput in 3.x)
$this->input->set('view', 'Abc');
parent::display();
}
_
/ views/abc/view.raw.php
_<?php
defined('_JEXEC') or die;
jimport('joomla.application.component.view');
class SimilarViewAbc extends JViewLegacy
{
function display($tpl = null)
{
parent::display($tpl);
}
}
_
/ views/abc/tmpl/default.php
_<?php
echo "Hello World from /views/abc/tmpl/default.php";
_
注:これは、HTMLを返す必要がある場合に使用するソリューションです(よりクリーンでJoomlaロジックに従います)。単純なJSONデータを返す方法については、以下を参照してすべてをコントローラーに配置してください。
Ajaxリクエストをsubcontrollerに送信すると、次のようになります。
_index.php?option=com_similar&controller=abc&format=raw
_
(rawビューの)サブコントローラー名は_abc.raw.php
_である必要があります。
これは、Abcという名前の2つのサブコントローラーがある/する可能性があることも意味します。
JSONを返す場合は、_format=json
_および_abc.json.php
_を使用するのが理にかなっています。 Joomla 2.5で。このオプションが機能するためにいくつかの問題があった(どういうわけか出力が破損した)ため、そのまま使用しました。
有効なJSON応答を生成する必要がある場合、ドキュメントページをチェックしてください JSON出力の生成
_// We assume that the whatver you do was a success.
$response = array("success" => true);
// You can also return something like:
$response = array("success" => false, "error"=> "Could not find ...");
// Get the document object.
$document = JFactory::getDocument();
// Set the MIME type for JSON output.
$document->setMimeEncoding('application/json');
// Change the suggested filename.
JResponse::setHeader('Content-Disposition','attachment;filename="result.json"');
echo json_encode($response);
_
通常、このコードはコントローラーに配置します(エンコードするデータを返すモデルを呼び出します-非常に一般的なシナリオです)。さらに理解する必要がある場合は、未加工の例と同様に、JSONビュー(view.json.php)を作成することもできます。
Ajaxリクエストが機能するようになったので、まだページを閉じないでください。以下をお読みください。
リクエストの偽造をチェックすることを忘れないでください。 JSession::checkToken()
は、ここで役立ちます。追加方法のドキュメントを読む フォームへのCSRFなりすまし
リクエストで言語名を送信しない場合、Joomlaが必要な言語文字列を翻訳しないことがあります。
何らかの方法でlangパラメータをリクエストに追加することを検討してください(_&lang=de
_など)。
Joomla 3.2の新機能! -コンポーネントをビルドせずにハンドルリクエストを作成できるようになりました
Joomla!Ajaxインターフェース -Joomlaは、プラグインまたはモジュールでAjaxリクエストを処理する軽量な方法を提供するようになりました。 Joomlaを使いたいかもしれません!コンポーネントがまだない場合、またはすでに持っているモジュールからリクエストを行う必要がある場合は、Ajaxインターフェース。
これは非常によく回答された質問に対する遅い回答ですが、AJAX呼び出しでコンポーネントのデータにアクセスする簡単な方法が必要な場合のために、この簡単な解決策を追加したいと思いました。
Joomlaのすべてのバージョン、サードパーティの可能性、グーグルで数日かけて見つけたハッキングで、これは私が思いつくことができる最も簡単なアプローチでした-フィードバックは間違いなく高く評価されています。
execute
を追加しましたタスクを呼び出す/実行するURL:
www.mysite.com/index.php?option=com_example&task=ForAjax.mytaskname
変更されたメインコントローラ\ com_example\controller.php
class ExampleController extends JControllerLegacy {
public function display($cachable = false, $urlparams = false) {
$app = JFactory::getApplication();
$view = $app->input->getCmd('view', 'default');
$app->input->set('view', $view);
parent::display($cachable, $urlparams);
return $this;
}
public function execute()
{
// Not technically needed, but a DAMN good idea. See http://docs.joomla.org/How_to_add_CSRF_anti-spoofing_to_forms
// JSession::checkToken();
$task = JFactory::getApplication()->input->get('task');
try
{
parent::execute($task);
}
catch(Exception $e)
{
echo new JResponseJson($e);
}
}
}
新しいサブコントローラー\ com_example\controllers\forajax.php
require_once JPATH_COMPONENT.'/controller.php';
class ExampleControllerForAjax extends ExampleController
{
public function MyTaskName()
{
$app = JFactory::getApplication();
$data['myRequest'] =$_REQUEST;
$data['myFile'] =__FILE__;
$data['myLine'] ='Line '.__LINE__;
$app->enqueueMessage('This part was reached at line ' . __LINE__);
$app->enqueueMessage('Then this part was reached at line ' . __LINE__);
$app->enqueueMessage('Here was a small warning at line ' . __LINE__, 'warning');
$app->enqueueMessage('Here was a big warning at line ' . __LINE__, 'error');
$task_failed = false;
echo new JResponseJson($data, 'My main response message',$task_failed);
$app->close();
}
}
レンダリングされたJSON出力
{
success: true,
message: "My main response message",
messages: {
message: [
"This part was reached at line 26",
"Then this part was reached at line 27"
],
warning: [
"Here was a small warning at line 28"
],
error: [
"Here was a big warning at line 29"
]
},
data: {
myRequest: {
option: "com_example",
task: "mytaskname",
Itemid: null
},
myFile: "C:\mysite\components\com_example\controllers\forajax.php",
myLine: "Line 24"
}
}
バレンティンの答えは良いですが、すでに構築されているコンポーネントに1つまたは2つのajax呼び出しを追加するだけの場合は、やや複雑すぎます。個別にcontroller.raw.php
またはview.raw.php
ファイル。
このajax呼び出しを行うには
index.php?format=raw&option=com_example&controller=job&task=keep_alive&tokenhash=1
job
サブコントローラー
public function keep_alive() {
$this->ajax_check();
//Do your processing and echo out whatever you want to return to the AJAX call
header('HTTP/1.1 202 Accepted', true, 202);
echo 'OK';
JFactory::getApplication()->close();
}
// Verifies jtoken and does a basic check that this is actually an AJAX call
private function ajax_check() {
if(!JSession::checkToken('GET') || !isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') {
header('HTTP/1.1 403 Forbidden', true, 403);
JFactory::getApplication()->close();
}
}
バレンティンの答えは良いです。
私はこのためにエンコーディングとエラー処理を処理するjsonコントローラーを好みます。json基本クラスを作成しました。
class itrControllerJson extends JControllerLegacy {
/** @var array the response to the client */
protected $response = array();
public function addResponse($type, $message, $status=200) {
array_Push($this->response, array(
'status' => $status,
'type' => $type,
'data' => $message
));
}
/**
* Outputs the response
* @return JControllerLegacy|void
*/
public function display() {
$response = array(
'status' => 200,
'type' => 'multiple',
'count' => count($this->response),
'messages' => $this->response
);
echo json_encode($response);
jexit();
}
}
このコントローラーは、次のような作業を行うコントローラークラスによって拡張されます。
require_once __DIR__.'json.php';
class componentControllerAddress extends itrControllerJson {
public function get() {
try {
if (!JSession::checkToken()) {
throw new Exception(JText::_('JINVALID_TOKEN'), 500);
}
$app = JFactory::getApplication();
$id = $app->input->get('id', null, 'uint');
if (is_null($id)) {
throw new Exception('Invalid Parameter', 500);
}
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('*');
$query->from('#__table');
$query->where('id = '.$db->quote($id));
$db->setQuery($query);
$response = $db->loadObject();
$this->addResponse('message', $response, 200);
} catch (Exception $e) {
$this->addResponse('error', $e->getMessage(), 500);
}
$this->display();
}
}
そしてあなたはこのようにリクエストを呼び出します:
index.php?option=com_component&task=address.get&format=json&id=1234&tokenhash=1
トークンハッシュは、JSession :: getFormToken()によって生成されます。したがって、完全な完全な呼び出しは次のようになります。
$link = JRoute::_('index.php?option=com_component&task=address.get&format=json&id=1234&'.JSession::getFormToken().'=1', false);
2番目のパラメーターは「false」に設定されているため、xmlを書き換えることなく、JavaScript呼び出しでこれを使用できます。
Javascript出力を追加するサードパーティのプラグインがないと100%確信している場合は、純粋なjson_encodeで問題ありません。
しかし...たとえば、JomSocialはサイト全体に「」を追加します。
だから...便利なトリック、json_encodeをタグでラップし、JavaScript側で処理します。
echo '@START@' . json_encode(...) . '@END@';
タスクでコントローラー名を使用して、コントローラーに直接アクセスできます。
index.php?option=com_similar&task=controller.abc&format=raw
呼び出します:controller.raw.php(戻り値はraw)
index.php?option=com_similar&task=controller.abc
呼び出します:controller.php(die;
を使用しない場合、戻り値はhtmlです)