Joomla를위한 커스텀 컴포넌트를 개발 중입니다! 3.x이며 AJAX를 호출하여 일부 데이터를 검색하려고합니다. 올바른 방법은 무엇입니까?
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
뷰를 사용할 컨트롤러를 생성하는 Abc
대신 view.raw.html 파일 (일반 뷰 파일과 동일)을 포함하는을 가정 해 봅시다 .
아래에는 원시 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 요청을 서브 컨트롤러에 요청하면
index.php?option=com_similar&controller=abc&format=raw
(원시보기의 경우) 서브 컨트롤러 이름은이어야 abc.raw.php
합니다.
이것은 또한 Abc라는 2 개의 서브 컨트롤러가있을 수 있음을 의미합니다.
당신이 JSON을 반환 할 경우, 사용하는 의미가 있습니다 format=json
와 abc.json.php
. Joomla 2.5에서. 이 옵션이 작동하는 데 문제가 있었으므로 (어떻게 출력이 손상되었으므로) raw를 사용했습니다.
유효한 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의 새로운 기능! -구성 요소를 구축하지 않고도 처리 요청을 할 수 있습니다
줌라! Ajax 인터페이스 -Joomla는 이제 플러그인 또는 모듈에서 Ajax 요청을 처리하는 간단한 방법을 제공합니다. Joomla를 사용하고 싶을 수도 있습니다! 아직 컴포넌트가 없거나 모듈에서 요청을해야하는 경우 Ajax 인터페이스.
JRequest
습니까? $this->input
v3.x를 사용 하기 때문에 단순히 더 이상 사용되지 않습니까?
JRequest
. 감사
Valid JSON Response
섹션 에서 언급했습니다 .
이것은 매우 잘 대답 된 질문에 대한 늦은 대답이지만, 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"
}
}
Valentin의 대답은 훌륭하지만 이미 작성된 구성 요소에 1 또는 2 개의 ajax 호출을 추가하는 것만으로도 지나치게 복잡합니다. 그것은 별도 제작하지으로 도망 완벽하게 가능 controller.raw.php
또는 view.raw.php
파일을.
이 아약스 전화를 걸려면
index.php?format=raw&option=com_example&controller=job&task=keep_alive&tokenhash=1
에서 job
subcontroller
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);
두 번째 매개 변수는 "false"로 설정되어 있으므로 XML 재 작성없이 자바 스크립트 호출에서이 매개 변수를 사용할 수 있습니다.
JResponseJson
클래스를 사용 하여 처리 하지 않는 이유는 무엇입니까?