Dodanie admin-ajax.php do interfejsu użytkownika. Dobry czy zły pomysł?

17

Uwielbiam admin-ajax.php. Ale nienawidzę konieczności lokalizowania w celu wskazywania skryptów frontendowych i żałuję, że nie ma równoważnego, łatwego do znalezienia pliku dla motywów. (Niepokoi mnie to również, że żądania frontendu przechodzą przez „/ wp-admin /”. Bez praktycznego powodu, po prostu wygląda brzydko IMO.)

Więc po prostu skopiowałem admin-ajax.php do katalogu głównego w "/ajax.php", poprawiłem ścieżki dołączania i usunąłem stałą definicję WP_ADMIN. Wygląda na to, że działa jak gangbustery (mogę teraz po prostu skierować wszystkie moje żądania AJAX frontendu do /ajax.php! I nadal mogę używać normalnych haków wp_ajax w moich wtyczkach!).

Ale czy to bezpieczne? Co może pójść nie tak? Ponieważ nie jest to wbudowane w rdzeń, zakładam, że istnieje dobry powód, dlaczego nie. Ale przeglądając kod, nie widzę żadnych bezpośrednich problemów.

Jesteś sprytny - powiedz mi, czy to podejście jest szalone. Lub jeśli istnieje prostsza metoda, którą przeoczam.

MathSmath
źródło
Możesz zapomnieć o tym pliku i przeoczyć go podczas automatycznych aktualizacji, co może spowodować uszkodzenie i pozostawienie luk bezpieczeństwa.
Hemm

Odpowiedzi:

19

Możesz po prostu użyć RewriteRule do swojego .htaccess powyżej zwykłych reguł przepisywania bezpośredniego linku:

RewriteRule ^ajax$ /wp-admin/admin-ajax.php [L]

Teraz wysyłaj żądania AJAX example.com/ajaxi nigdy nie przegap podstawowych zmian w tym pliku po uaktualnieniach.

fuxia
źródło
Świetny pomysł! To jedna z tych rzeczy, które po usłyszeniu myślą „to takie proste i oczywiste!” Dzięki.
MathSmath,
Dodałem regułę przepisywania zgodnie z twoją sugestią, ale example.com/ajaxadres URL 404. Czy mógłbyś wyjaśnić, gdzie dokładnie .htaccesspowinienem to dodać? Mam w tej chwili między # BEGIN WordPress <IfModule mod_rewrite.c>i</IfModule> # END WordPress
Jana
To działa. Brakowało mi końcowego ukośnika. Mam permalinki ustawione na /% postname% /
John
7

Po pierwsze: normalizacja. Jeśli planujesz używać wtyczek społecznościowych, prawdopodobnie nie będą one troszczyć się o ciebie/ajax.php plikiem w katalogu głównym dokumentu. Więc nie będą go używać.

Jeśli masz zamiar rzucić wszystko sam, to nie jest problem.

Po drugie: co jeśli podstawowe aktualizacje? Czy będziesz monitorować i zmieniać plik ajax?

Po trzecie : pomimo admin-ajax.phpprzebywania w wp-adminnim, nie ładuje żadnych elementów obszaru administracyjnego (np. Tabel list itp.). Nie sprawdza też autoryzacji ani nie ujawnia niczego wrażliwego na niezalogowanych użytkowników. Innymi słowy, to tak jak plik frontonu. Nie ma się o co martwić.

Po czwarte: W związku z pierwszym problemem niektóre wtyczki sprawdzą przed ślepym załadowaniem funkcji powiązanych z ajaxem. Przykład jest poniżej. Zmodyfikowany ajax.php prawdopodobnie nie spowoduje załadowania.

<?php
if (is_admin() && defined('DOING_AJAX') && DOING_AJAX) {
    //  load ajax stuff
}

Wreszcie: na co narzekasz, warto skorzystać z lokalizacji w celu uzyskania adresu URL Ajax. Dlaczego? Ponieważ Twoje pliki JS nie są świadome żadnych rzeczy po stronie serwera. Będziesz miał trudny URL, który się zepsuje, jeśli / kiedy strona się poruszy? Wygląda na zły wybór.

Jeśli naprawdę nie chcesz lokalizować każdego skryptu korzystającego z Ajax, po prostu podpisz się wp_headbardzo wcześnie i wypluj adres URL administratora aukcji. Problem rozwiązany (tak przy okazji, właśnie tak robi to admin).

<?php
add_action('wp_head', 'wpse83650_lazy_ajax', 0, 0);
function wpse83650_lazy_ajax()
{
    ?>
    <script type="text/javascript">
    /* <![CDATA[ */
    var ajax_url = "<?php echo esc_js(admin_url('admin-ajax.php')); ?>";
    /* ]]> */
    </script>
    <?php
}
chrisguitarguy
źródło
Dzięki, Chris! Wszystkie ważne punkty. Najważniejszą rzeczą, którą mi pomogłeś, jest to, że chociaż nie myślałem o tym jako o „hackowaniu rdzenia” (ponieważ dodawałem, nie modyfikowałem pliku), tak naprawdę jest, ponieważ zależy to od innych funkcji w rdzeniu, które mogą się zmienić . Nie różni się zbytnio od żadnej innej wtyczki (która może również umrzeć po zmianach podstawowej funkcjonalności), ale zdecydowanie różni się filozoficznie. Dzięki za myśli!
MathSmath
Odp: „ Po trzecie: ... Nie ma się czym martwić. ”, A co z próbą zablokowania katalogu wp-admin, np. Przy użyciu reguł .htaccess w celu ograniczenia do znanych bezpiecznych zakresów adresów IP? Zakładam, że należy wprowadzić wyjątek dla pliku ajax-admin.php? (Mówię „zakładaj”, ponieważ jestem niepoprawny, jeśli chodzi o reguły .htaccess i nie wiem, czy to możliwe?).
Sepster
Tak, powinno być możliwe zezwolenie na pojedynczy plik.
chrisguitarguy
@chrisguitarguy to świetna odpowiedź, dziękuję. Usiłuję załadować admin-ajax na fronton, ponieważ odwracam proxy siteurl do mojego adresu URL tymczasowego / domowego. Spójrz na to: link Czy można to zrobić za pomocą wtyczki innej firmy? Czy moje podejście jest nieprawidłowe?
paranza
5

Podobnie jak w przypadku wielu rzeczy w WordPress, istnieje prawie nieskończona liczba sposobów na skórowanie kota. Podczas gdy wszystkie zaakceptowane metody działają, okazało się, że są mniej „schludne” niż użycie wp_localize_script do włączenia funkcji ajax na interfejsie.

Sprawdź to:

add_action( 'wp_enqueue_scripts', 'se83650_js' );
function se83650_js()
{
    wp_enqueue_script( 'se83650-js', plugin_dir_url( __FILE__ ) . 'js/se83650.js',  'jquery', '1.0.0', true );
    // First param is the name of the script you are attaching it to - in this case
    // it is the name of the custom script we added.  Second param is the name of 
    // the javscript Object that will be attached with your information.
    // Third param is an array of attributes, in this case, ajaxurl
    wp_localize_script( 'se83650-js', 'se83650Ajax', 
        array(
            // You can put any variables here you want for your script
            // such as plugin-specific variables or nonces, etc.
            'ajaxurl'    => admin_url( 'admin-ajax.php' )
        )
    );
}

A następnie w se83650.jspliku odwołujesz się do swojej zmiennej se83650Ajax.ajaxurl.

Zaletą tej techniki jest to, że jeśli skończysz z wieloma wtyczkami, które próbują powielić tę funkcjonalność, nie zawierają one ani nie zastępują tej samej zmiennej. ajaxurljest dość ogólny do włączenia, dzięki czemu jesteś bardziej opanowany i gra lepiej z innymi programistami.

blogerzy
źródło