You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails 5.2 如何向第三方自定义Widget返回JSON搜索结果

跨域Widget搜索结果返回最优方案

不需要额外新增模型字段、不需要让客户引入第二个JS脚本,通过CORS配置+内置前端提交回调的方案即可实现需求,具体实现步骤如下:

1. 配置跨域资源共享(CORS)

首先安装rack-cors gem处理跨域请求权限:

# Gemfile
gem 'rack-cors'

执行bundle install后新增CORS配置文件:

# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*' # 生产环境替换为客户实际域名,多个域名用逗号分隔
    resource '*', headers: :any, methods: [:get, :post, :options]
  end
end

2. 调整表单结构,预留结果容器

修改search_form.html.erb,去掉默认的remote: true配置,新增表单ID和结果容器:

<%= bootstrap_form_for @search, :html => {id: "search-widget-form"}, :url => create_search_url(@search) do |form| %>
  <%=form.select :beds, (select_options), {prompt: "Min # of Bedrooms", hide_label: true}, {class: "form-control form-control-sm"}%>
  <%=form.select :max_price, (100000..2000000).step(10000).map{|x| number_to_currency(x, precision: 0)}, {hide_label: true, prompt: "Select Max Price"}, {class: "form-control form-control-sm", id: "sale_price"}%>
  <input type="submit" name="commit" value="SEARCH" class="btn btn-danger">
<% end %>
<div id="search-widget-results" style="margin-top: 20px;"></div>

3. 内置提交回调逻辑到原有JS资源

修改SearchapisController的js_constructor方法,把表单提交、请求接口、渲染结果的逻辑直接打包到客户引入的search_form.js中,无需额外引入其他资源:

private
  def js_constructor
    form_content = render_to_string('search_form', layout: false)
    js_content = <<~JS
      document.write(#{form_content.to_json});
      // 监听表单提交事件
      document.getElementById('search-widget-form').addEventListener('submit', async function(e) {
        e.preventDefault();
        const submitBtn = this.querySelector('input[type="submit"]');
        const originalBtnText = submitBtn.value;
        submitBtn.disabled = true;
        submitBtn.value = 'Finding Schools...';
        
        // 序列化表单数据发起请求
        const formData = new FormData(this);
        const resultContainer = document.getElementById('search-widget-results');
        resultContainer.innerHTML = '';
        
        try {
          const res = await fetch('#{create_search_url}', {
            method: 'POST',
            body: formData
          });
          const results = await res.json();
          
          // 自定义结果渲染逻辑,可根据需求调整样式和字段
          if(results.length > 0) {
            let html = '<h4>搜索结果</h4><ul class="search-results-list">';
            results.forEach(item => {
              html += `<li>房源:${item.title} / 价格:${item.price}</li>`;
            });
            html += '</ul>';
            resultContainer.innerHTML = html;
          } else {
            resultContainer.innerHTML = '<p>暂无匹配的房源</p>';
          }
        } catch(err) {
          resultContainer.innerHTML = '<p>搜索失败,请稍后重试</p>';
          console.error('搜索请求错误', err);
        } finally {
          submitBtn.disabled = false;
          submitBtn.value = originalBtnText;
        }
      });
    JS
    js_content
  end

4. 生产环境优化建议

  • 将CORS配置中的*替换为客户实际域名,避免接口被恶意调用
  • 可新增客户身份校验逻辑,给每个接入的客户分配唯一标识,请求时携带校验,防止接口滥用
  • 可对搜索结果渲染样式做统一封装,支持客户自定义配色等参数适配不同站点风格

内容的提问来源于stack exchange,提问作者tomb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:06:05