উপাদানটিতে AJAX কল করার সঠিক উপায় কী?


40

আমি জুমলার জন্য একটি কাস্টম উপাদান বিকাশ করছি! 3.x এবং কিছু ডেটা পুনরুদ্ধার করতে এর ভিতরে একটি এজাক্স কল করতে চান। এটি করার সঠিক উপায় কী?


গুরুত্বপূর্ণ পরামর্শটি জুমলার প্রবাহকে কখনও ভেঙে দেয় না। উদাহরণস্বরূপ কয়েকটি অংশে অজেক্স অনুরোধআফটাররউটে ইভেন্টে কাজটি করুন এবং অনুরোধটি নিজেই এখানে হত্যা করুন। এই ত্রুটিগুলির কারণগুলি যা ডিবাগ করা শক্ত।
শ্যাম

আপনার অর্থ - কোনও অ্যাপ্লিকেশন বন্ধ করবেন না? আপনি আরও বিস্তারিত বলতে পারেন?
দিমিত্রি রেকুন

হ্যাঁ, জুমলা যদি অ্যাপটি বন্ধ করে দেয় তবে এটি সেরা। সুতরাং আপনার এক্সটেনশনের এক্সটেনসিবিলিটি বজায় থাকবে।
শ্যাম

তবুও পুরোপুরি বুঝতে পারছি না। আমি যে বিষয়ে কথা বলছি তা হ'ল নিয়ন্ত্রকের মধ্যে থাকা $ অ্যাপ্লিকেশন-> বন্ধ ()। আপনি কি একই মানে? :)
দিমিত্রি রেকুন

হ্যাঁ, একই বক্তব্য। আমাদের অ্যাপ্লিকেশনটি কন্ট্রোলারে কেন বন্ধ করা উচিত, যখন এটি জুমলা নিজেই করবে।
শ্যাম

উত্তর:


47

দয়া করে নোট করুন যে এই উত্তরটি ইতিমধ্যে কয়েক বছরের পুরানো এবং আপডেট করা হয়নি। আপনি যদি কিছু মনে করেন না তবে নির্দ্বিধায় সম্পাদনা / মন্তব্য করতে পারেন।

বিমূর্ত

এটি মোকাবেলার প্রায় কোনও সরকারী উপায় নেই, এটি জটিলতার উপর নির্ভর করে এবং আপনি কাজটি করতে এমভিসি প্যাটার্নের উপর কতটা নির্ভর করতে চান।

জুমলা 2.5 এবং 3.x এ কী কাজ করা উচিত তা নীচে কয়েকটি সম্ভাব্য সমাধান রয়েছে। কোডটি কোনও অনুলিপি - পেস্ট কাজের জন্য নয় বরং একটি সাধারণ ধারণা হিসাবে উপস্থাপন করা হয়েছে।

জুমলার আগে! 3.2 নীচের উদাহরণগুলি ব্যবহার করার জন্য আপনার কেবলমাত্র জিনিসটি হ'ল একটি component। জুমলা ৩.২ (কম জটিল কাজের জন্য) পরে আপনি মডিউল এবং প্লাগইন থেকে অনুরোধ পরিচালনা করতে পারেন।


জেনেরিক এইচটিএমএল প্রতিক্রিয়া (উত্তরাধিকারের এমভিসি অনুসরণ করে)

টাস্কের জন্য আপনার ইউআরএলটি দেখতে এটির মতো হওয়া দরকার:

index.php?option=com_similar&task=abc&format=raw

আপনি কন্ট্রোলার তৈরি করার চেয়ে যা ভিউটি ব্যবহার করবে, আসুন আমরা বলি Abcযে এতে ভিউ.আরও এইচটিএমটিএল (একটি সাধারণ ভিউ ফাইলের সমান) থাকবে।

আপনার নীচে একটি কাঁচা এইচটিএমএল প্রতিক্রিয়া উত্পন্ন করার কোড রয়েছে:

/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";

দ্রষ্টব্য: এইচটিএমএল (এটি ক্লিনার এবং জুমলা যুক্তি অনুসরণ করে) করতে হলে আমি এই সমাধানটি ব্যবহার করব। সাধারণ জেএসওএন ডেটা ফেরত দেওয়ার জন্য, কীভাবে সবকিছু নিয়ামকের মধ্যে রাখবেন তা নীচে দেখুন।

Subcontrollers

আপনি যদি কোনও সাবকন্ট্রোলারের কাছে আপনার এজাক্স অনুরোধ করেন তবে :

index.php?option=com_similar&controller=abc&format=raw

আপনার সাবকন্ট্রোলারের নাম (কাঁচা ভিউয়ের জন্য) হওয়া দরকার abc.raw.php

এর অর্থ এটিও হ'ল আপনার কাছে Abc নামে 2 জন সাবকন্ট্রোলার থাকবে / থাকতে পারে।

আপনি যদি জেএসএনকে ফিরিয়ে দেন তবে এটি ব্যবহার করা বোধগম্য হতে পারে format=jsonএবং abc.json.php। জুমলা ২.৩ তে। এই অপশনটি কাজ করার ক্ষেত্রে আমার কিছু সমস্যা হয়েছিল (কোনওভাবে আউটপুট দূষিত হয়েছিল), তাই আমি কাঁচা ব্যবহার করেছি।


বৈধ JSON প্রতিক্রিয়া (নিম্নলিখিত নতুন / উত্তরাধিকার MVC)

আপনার যদি কোনও বৈধ 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);

আপনি নিয়মিতভাবে এই কোডটি নিয়ামকের মধ্যে রাখতেন (আপনি এমন একটি মডেল কল করবেন যা আপনাকে এনকোড করা ডেটা ফেরত দেবে - একটি খুব সাধারণ দৃশ্য)। আপনার যদি এটি আরও এগিয়ে নেওয়া দরকার তবে আপনি কাঁচা উদাহরণের অনুরূপ জেএসএন ভিউ (ভিউ.জসন.এফপি )ও তৈরি করতে পারেন।


নিরাপত্তা

এখন যে আজাক্স অনুরোধ কাজ করছে, পৃষ্ঠাটি এখনও বন্ধ করবেন না। নীচের পড়া.

অনুরোধ জালিয়াতির জন্য পরীক্ষা করতে ভুলবেন না। JSession::checkToken()এখানে কাজে আসা। ফর্মগুলিতে সিএসআরএফ-অ্যান্টি-স্পুফিং কীভাবে যুক্ত করবেন তার ডকুমেন্টেশন পড়ুন


বহুভাষা সাইট

এটি ঘটতে পারে আপনি অনুরোধে ভাষার নামটি না পাঠালে, জুমলা আপনার পছন্দমতো ভাষার স্ট্রিং অনুবাদ করবে না।

আপনার অনুরোধে (যেমন &lang=de) কোনওভাবে ল্যাং পরম যুক্ত করার বিষয়টি বিবেচনা করুন ।


জুমলা আজাক্স ইন্টারফেস

জুমলা ৩.২ এ নতুন! - আপনাকে কোনও উপাদান তৈরি না করে হ্যান্ডেল অনুরোধগুলি করতে সক্ষম করে

জুমলা আজাক্স ইন্টারফেস - জুমলা এখন একটি প্লাগইন বা মডিউলে অ্যাজাক্স অনুরোধ পরিচালনা করার জন্য একটি হালকা ওজনের উপায় সরবরাহ করে। আপনি জুমলা ব্যবহার করতে পারেন! যদি আপনার ইতিমধ্যে কোনও উপাদান না থাকে বা আপনার যদি ইতিমধ্যে থাকা কোনও মডিউল থেকে অনুরোধ করতে হয় তবে আজাক্স ইন্টারফেস।


9
আমি এখনও অবধি joomla.stackexchange.com এ দেখেছি সেরা মানের উত্তর - খুব ভালভাবে সম্পন্ন হয়েছে এবং বারটি বাড়ানোর উপায়। চমৎকার কাজ!
NivF007

রাজি, তবে কি JRequest? $this->inputআমি v3.x ব্যবহার করার পরে এটি অবহেলা করা উচিত?
দিমিত্রি রেকুন

1
আমি আপনার উদ্বেগ সম্পর্কিত সম্বোধন JRequest। ধন্যবাদ
ভ্যালেন্টিন দেশপা

3
উত্তম উত্তর, কেবল উল্লেখ করতে চেয়েছিলেন যে ৩.১ থেকে একটি জুমলা বর্গ রয়েছে যা JSON আউটপুট পরিচালনা করে: এপিআই , ব্যবহার
ফ্রুপেল

@ fl0r ইয়াপ, ভ্যালেন্টাইন Valid JSON Responseবিভাগে এটি উল্লেখ করেছেন ।
দিমিত্রি রেকুন

20

এটি এই খুব ভাল উত্তর দেওয়া প্রশ্নের দেরি করে দেওয়া উত্তর, তবে আমি এই কাট টু দ্য চেজ সলিউশনটি যুক্ত করতে চেয়েছিলাম যাদের কেবলমাত্র একটি এজেএক্স কল দিয়ে তাদের উপাদানগুলির ডেটা পাওয়ার জন্য একটি সহজ উপায় প্রয়োজন।

সমস্ত জুমলা সংস্করণ, তৃতীয় পক্ষের সম্ভাবনা এবং হ্যাকগুলি যা গুগল করার বেশ কয়েকটি দিনের মধ্যে আমি খুঁজে পেয়েছি, এটিই আমার সাথে আসা সহজতম পদ্ধতির - এবং প্রতিক্রিয়াটি অবশ্যই প্রশংসিত।

  1. executeআমার বিদ্যমান প্রধান নিয়ামকটিতে ফাংশন যুক্ত হয়েছে
  2. আমি এজেএক্সের সাথে কল করতে চেয়েছি সেই টাস্কের জন্য সর্বজনীন ক্রিয়াকলাপ সহ একটি উপকন্ট্রোলার তৈরি করেছে
  3. আউটপুট পরিচালনা করার জন্য জুমলা জেআরএসপোনসজেসন শ্রেণিতে অন্তর্নির্মিত ব্যবহৃত হয়েছে ( এটি সত্যিই দুর্দান্ত! )

কলটি করতে / কার্য সম্পাদনের জন্য ইউআরএল:

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 \ কন্ট্রোলার \ 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();
    }
}

জেন্ডার জেএসএন আউটপুট সরবরাহ করেছে

{
    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"
    }
}

11

ভ্যালেন্টিনের উত্তরটি ভাল তবে কিছুটা অতিরিক্ত জটিল যদি আপনার যা করতে হবে তার মধ্যে ইতিমধ্যে নির্মিত কোনও উপাদানটিতে 1 বা 2 অজ্যাক্স কল যুক্ত করা উচিত। পৃথক controller.raw.phpবা view.raw.phpফাইল না তৈরি করে পালানো পুরোপুরি সম্ভব ।

এই এজ্যাক্স কল করতে

index.php?format=raw&option=com_example&controller=job&task=keep_alive&tokenhash=1

ইন jobsubcontroller

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();
    }
}

7

ভ্যালেন্টিনের উত্তর ভাল।

আমি এমন একটি জসন কন্ট্রোলারকে পছন্দ করি যা এর জন্য এনকোডিং এবং ত্রুটি হ্যান্ডলিং পরিচালনা করে আমি একটি জসন বেস শ্রেণি তৈরি করেছি:

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

টোকেন হ্যাশটি জেএসশন :: গেটফর্মটোকেন () দ্বারা উত্পাদিত হয়েছে। সুতরাং সম্পূর্ণ সম্পূর্ণ কলটি এর মতো হতে পারে:

$link = JRoute::_('index.php?option=com_component&task=address.get&format=json&id=1234&'.JSession::getFormToken().'=1', false);

দ্বিতীয় প্যারামিটারটি "ভুয়া" তে সেট করা আছে যাতে আমরা এটি এক্সএমএল পুনরায় লেখা ছাড়াই জাভাস্ক্রিপ্ট কলগুলিতে ব্যবহার করতে পারি।


1
ভাল লাগছে, তবে কেন JResponseJsonএটি পরিচালনা করার জন্য ক্লাস ব্যবহার করবেন না?
দিমিত্রি রেকুন

জেআরস্পোনজসন জুমলা 3
আনিবাল

কোনও জুমলা এসই ছিল না যেখানে আমি জিজ্ঞাসা করতে পারি;)
হ্যারাল্ড লেথনার

4

আপনি যদি 100% নিশ্চিত হন যে কোনও জাভাস্ক্রিপ্ট আউটপুট যুক্ত করার কোনও থ্রিড-পার্টি প্লাগইন নেই, একটি খাঁটি json_encode ঠিক আছে।

তবে ... উদাহরণস্বরূপ জমসোকিয়াল পুরো সাইটে "" যুক্ত করে।

সুতরাং ... একটি কার্যকর কৌশল, জাসন_এনকোড ট্যাগ সহ মোড়ানো, এবং এটি জাভাস্ক্রিপ্টের পাশে প্রসেস করুন।

echo '@START@' . json_encode(...) . '@END@';

3

আপনি কার্যটিতে নিয়ামকের নাম ব্যবহার করে সরাসরি কোনও নিয়ামক অ্যাক্সেস করতে পারেন:

index.php?option=com_similar&task=controller.abc&format=raw

কল করবে: controller.raw.php (ফিরতি কাঁচা)

index.php?option=com_similar&task=controller.abc

কল করবে: controller.php (আপনি ব্যবহার না করলে ফিরতি এইচটিএমএল die;)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.