JQuery AJAX 发布和刷新页面内容而不重新加载页面

Posted

技术标签:

【中文标题】JQuery AJAX 发布和刷新页面内容而不重新加载页面【英文标题】:JQuery AJAX Post and Refresh Page Content without reload page 【发布时间】:2012-12-15 06:52:24 【问题描述】:

现在我知道我有可能在这里提出重复的问题,但是我真的不知道要搜索什么,因为我是一个完整的 AJAX jQuery 菜鸟。相信我,我已经尝试搜索我认为显而易见的东西,但没有运气,所以请放轻松。

我有一个 php wordpress 网站,默认以英镑显示价格。顶部是一个带有onchange="this.form.submit()" 的选择框,允许用户更改所有报价的默认货币。

<form method="post" action="">
    <select name="ChangeCurrency" onChange="this.form.submit()">
        <option value="GBP">GBP</option>
        <option value="USD">USD</option>
        <option value="EUR">EUR</option>
    </select>
</form>

主页上有几个,我称之为“短代码小部件”,每个都包含产品和价格表。如果您愿意,可以使用仪表板。

目前的工作方式(低效):

    用户更改选择。 已提交表单 主页重新加载了所选货币的最新价格。

这不好,因为每当有人更改货币时,整个页面都会重新加载(这需要时间,在没有缓存的情况下传输大约 1mb,更不用说服务器上不必要的负载了)。

我想要的(更高效):

    更改选择框时,我希望异步发布更改货币会话变量的表单。 每个“短代码小部件”都会一一更新,而无需重新加载整个页面。

这是jquery可以做到的吗?我从哪里开始?

以防万一它有什么不同,以便您明白我的意思,这里是 URL,以便您可以看到我在说什么...http://bit.ly/10ChZys

第 2 部分: 由于下面的答案混搭,我使用 jQuery 和 ajax 来更新 fixTable...我使用会话变量来存储用户的选择,这样,如果他们返回站点,选项将被保存。

我的代码有问题,因为存储在 http://goldealers.co.uk/wp-content/plugins/gd/tables.php?currency=GBP&table=fixTable 中的会话变量似乎与用户的会话 ID 具有不同的 session_id,因为不再存储该选项。

有没有办法告诉服务器它们是同一个会话?

解决方案 我使用 Ribot 的解决方案开始使用并解决了最初的问题,然后使用 NomikOS 的解决方案进行扩展......

【问题讨论】:

页面上有多少需要价格货币的产品? 它是表格产品定价。大约有 7 个表(简码小部件),每个表大约有 14 个需要更改的价格。目前在加载页面时以 php 计算价格。 【参考方案1】:

是的,jQuery 可以使用 ajax 来实现。

首先,在使用ajax时,你不必发布表单来获取数据。 jQuery中的ajax会加载一个url的文本数据。

您可以先给您的选择一个 id(此处为 id="changeCurrency"),然后:

$("#changeCurrency").change(function()
    currency = $('#changeCurrency option:selected').val() // get the selected option's value
    $("#some_div").load("someurl.php?currency=" + currency);
);

现在阅读 jQuery 和 ajax,了解您需要执行哪种 ajax 调用来最适合您的需求。

【讨论】:

既然可以使用$(this).val(),为什么还要使用$('#changeCurrency option:selected').val() 我的每个简码小部件都是在函数中生成的。是否可以让 jquery 获取一个 php 脚本来调用该函数并使用从 php 函数返回的 html 数据的内容生成 html(替换整个 div 内容)? Gravy:是的,如果你的php函数只能在url.php页面上输出你需要的html,并且div有id="div_id",你可以做$("#div_id").load ("url.php") popnoodles:假设有人不喜欢使用“this”来表达更加清晰? 我想我喜欢这种方法。这似乎是最简单和优雅的解决方案。对于每个仪表板小部件,我将注入 html 以替换我的简码函数中的现有表。我会试一试,让你们都知道它是怎么回事。在接下来的几天里,我可能会向您提出更多问题......谢谢。 :)【参考方案2】:

注意:这个答案显示了关于 AJAX 进程的 php 后端的一些想法。它是关于前端过程的其他答案的补充。

1.- 在 WP 中管理 AJAX 请求的模型,只是一些想法,好吗?

add_action('init', 'process_ajax_callback');

function process_ajax_callback()

    if ( ! $_REQUEST['go_ajax'])
    
        return;
    

    try
    
        if (isset($_REQUEST['nonce_my_ajax']))
        
            $nonce   = $_REQUEST['nonce_my_ajax'];
            if ( ! wp_verify_nonce($nonce    = $_REQUEST['nonce_my_ajax'], 'nonce_my_ajax'))
            
                throw new Exception("Nonce token invalid."); // security
            
        
    
    catch (Exception $e)
    
        $output['result']    = false;
        $output['message']   = $e->getMessage();

        echo json_encode($output);
        exit;
    

    $result  = true;
    $message = '';

    switch ($_REQUEST['action'])
    
        case 'update_price':
        try
        
            // update price
            // price value comes in $_REQUEST['price']
        
        catch (Exception $e)
        
            $result              = false;
            $message             = $e->getMessage();
        
        break;      

        case 'other_actions':
        break;      
    

    $output['result']    = $result ? true : false;
    $output['message']   = $message;

    echo json_encode($output);
    exit;

2.- 不要忘记安全

// nonce_my_ajax is passed to javascript like this:
wp_localize_script('my_js_admin', 'myJsVars', array(
    'nonce_my_ajax'  => wp_create_nonce('nonce_my_ajax')
));

3.- 一般来说,前端所需的(与上面显示的后端模型一起使用)是这样的:

$("select[name='ChangeCurrency']").live("change", function() 
    var price = $(this).val();
    $.post(
            window.location.href,
            
                go_ajax : 1, // parse ajax
                action : 'update_price', // what to do
                price : price, // vars to use in backend
                nonce_my_ajax : myJsVars.nonce_my_ajax // security
            ,
            function(output) 
            if ( output.result == true )
                // update widgets or whatever
                // $("#my_div").html("we happy, yabadabadoo!");
                // or do nothing (AJAX action was successful)
            else
                alert(output.message)
            , 'json');
);

4.- 您可以使用$.get()$.post() 向/在服务器中发送/处理数据,但.load() 在更新数据库时并不好,因为您无法管理返回的失败消息,精度为json 响应(例如:倍数验证错误消息)。只需使用 .load() 加载 HTML 视图。

更新:

设置session_id() where 可以在正常请求和 ajax 请求中执行,并且尽可能在早期执行。我希望你正在使用一个类来包装你的插件,如果不是现在是时候做它......示例:

class my_plugin 

    function __construct()
    
        if ( ! session_id())
        
            session_start();
        

        add_action('init', array($this, 'process_ajax_callback'));

        // ...
       

    function process_ajax_callback()
    
        // ...
    

更新 2:

关于基于随机数的安全性:

WordPress 中可用的安全功能是“随机数”。一般来说,一个 “nonce”是只能使用一次的令牌,通常用于 防止未经授权的人代表他人提交数据 人。

参考:http://myatus.com/p/wordpress-caching-and-nonce-lifespan/

在这个模型中,nonce_my_ajax 只是一个例子,实际上它应该像nonce_my_plugin_name 那样更独特,或者更好的是nonce_my_plugin_name_what_action,其中what_action 代表updating user,或者inserting new book,等等...

更多信息:WP Codex: WordPress Nonces, WPtuts+: Capabilities and Nonces.

【讨论】:

您好 NomikOS。你能帮我处理这个随机数业务吗???这是否有助于防止例如 json 抓取??? @gravy 嗨,答案已更新...最后一期nonces 超出了与您的问题标题相关的范围。所以人们喜欢1Q=1A 风格。不要犹豫,打开一个新问题。 HNY 伙伴。【参考方案3】:

删除onchange并添加一个ID

<select name="ChangeCurrency" id="ChangeCurrency">...

在页面上以您的基础货币为您的所有价格提供价格并输出它们

<span class="price" data-base="0.12">&pound;0.12</span>

在你的JS中有一个转换表

// base currency is GBP
// each currency has 0: currency symbol, 1: conversion rate
var currency="GBP":["&pound;", 1], "USD":["&dollar;", 0.67];
var usercurrency=currency['GBP'];

并将事件绑定到更改

$('#ChangeCurrency').on('change', function()
    // post to the server to update it
    $.post(...);
    // set locally on the page
    usercurrency=currency[$(this).val()];
    // and change all the values
    $('.price').each(function()
        $(this).html(usercurrency[0] + (usercurrency[1] * $(this).data('base')).toFixed(2) );
    );
).trigger('change'); // trigger this to run on page load if you want.

我没有检查任何代码

【讨论】:

您好,谢谢。我会调查一下,但是你的方法让我担心 js 会降级...如果用户没有 js,或者 js 已关闭,我如何仍然允许用户提交表单以使用您的更改货币方法?我知道在上面的示例中,我有 onchange="this.form.submit()" 但这并不能阻止我添加一个说“提交”的按钮。 如果没有 JS,我写的事件不会被捕获,当他们按下提交时,一切都会如你所愿。

以上是关于JQuery AJAX 发布和刷新页面内容而不重新加载页面的主要内容,如果未能解决你的问题,请参考以下文章

使用 jquery/ajax 刷新/重新加载 Div 中的内容

如何在jquery ajax之后刷新网站的一部分而不刷新整个页面

使用Jquery时无法读取数据库,Ajax提交表单而不刷新页面

刷新数据表而不重新加载页面

更新页面上的数据而不刷新

更新页面上的数据而不刷新