ruby-on-rails - Rails 冲突 ajax 和 URI.encode
问题描述
我有一个搜索字符串,它通过我的控制器连接到我的书面库,并向第三方 api 发送获取请求。表格:
<%= form_with(:url => url_for(:controller => 'orders', :action => 'find_drug'), method: "get") do %>
<%= text_field_tag :drug_name, nil, class: "search_drug", placeholder:"Find drug..." %>
<%= button_to "Find", nil, class: "search_drug_button" %>
<% end %>
阿贾克斯:
$('document').ready(function() {
$('.search_drug_button').click(function(){
$.ajax({
url: 'orders/find_drug',
}).done(function(data) {
console.log(data);
});
});
});
控制器订单控制器:
def find_drug
response = ApiParser::Parser.new
drugs = response.get_drug(params[:drug_name]).response
respond_to do |format|
format.json { render json: drugs.body}
end
end
我的库中的方法(使用 HTTParty gem 编写):
module ApiParser
class Parser
include HTTParty
...
def get_drug(drug)
options = "?search.drugs={\"ls\": \"#{URI.encode(drug)}\"}"
self.class.get(options, format: :json)
end
...
end
end
在控制台中,发送了 2 个请求(其中一个表单,直接使用代码 200 发送到控制器,第二个通过 ajax)并且 ajax 给了我一个错误 500
NoMethodError in OrdersController#find_drug
undefined method `gsub' for nil:NilClass
Extracted source (around line #305):
#303 unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false)
#304 end
*305 str.gsub(unsafe) do
#306 us = $&
#307 tmp = ''
#308 us.each_byte do |uc|
Extracted source (around line #104):
#102 def escape(*arg)
#103 warn "#{caller(1)[0]}: warning: URI.escape is obsolete" if $VERBOSE
*104 DEFAULT_PARSER.escape(*arg)
#105 end
#106 alias encode escape
#107 #
Extracted source (around line #38):
**#this is my code**
*38 options = "?search.drugs={\"ls\": \"#{URI.encode(drug)}\"}"
#39 self.class.get(options, format: :json)
控制台 Chrome 200 中的请求:
...localhost:3000/orders/find_drug?utf8=%E2%9C%93&drug_name=%D1%8F%D1%80%&authenticity_token=Ndao2...
500:
...localhost:3000/orders/find_drug
如果在控制器中,而不是params[:drug_name],我只需传递我想要查找的字符串,则使用代码 200 的两个查询都可以工作。写完整个问题后,我认为我的 ajax 没有收到这个特定的params[:drug_name],并且无法搜索空值(但不完全是)。刚开始使用 javascript
我试图执行这样一个 Ajax 请求:
$('document').ready(function() {
$('.search_drug_button').click(function(e){
e.preventDefault();
$.ajax({
url: 'orders/find_drug',
data: new FormData($(this).closest("form")[0])
}).done(function(data){
console.log(data);
});
});
});
但我有一个错误
jquery-3.3.1.min.js:2 Uncaught TypeError: Illegal invocation
at i (jquery-3.3.1.min.js:2)
at jt (jquery-3.3.1.min.js:2)
at Function.w.param (jquery-3.3.1.min.js:2)
at Function.ajax (jquery-3.3.1.min.js:2)
at HTMLInputElement.<anonymous> (Аптечная_сеть:551)
at HTMLInputElement.dispatch (jquery-3.3.1.min.js:2)
at HTMLInputElement.y.handle (jquery-3.3.1.min.js:2)
解决方案
首先让我告诉你为什么你的代码不起作用。
- 您正在同时使用表单和 jQuery
- 如果你想使用 jQuery,你应该阻止提交按钮上发生的所有默认操作,
event.preventDefault();
否则你将发送两个请求,一个是默认表单提交,另一个是 jQuery。
解决方案:
您可以通过使用 rails 默认功能js.erb
。
让这个工作。
在您的控制器代码中使用它。
def find_drug
response = ApiParser::Parser.new
@drugs = response.get_drug(params[:drug_name]).response
end
- 注释掉你所有的
ajax
代码。 - 将您的代码替换为
form_with(url: '/orders/find_drug', method: :get)
- 在订单文件夹中创建一个文件为
find_drug.js.erb
- 写
console.log('<%= @data %>');
_find_drug.js.erb
现在检查一下。如果您仍然面临问题,请告诉我。
推荐阅读
- postgresql - kong :跨多个服务器复制数据
- spring - 用于回滚的多个 jdbcTemplate 和事务管理
- monitoring - 在 CloudWatch 中跨 ECS 任务实例聚合 codahale 指标计数
- couchdb - 同步数据库中的访问控制
- kubernetes - 什么是 Kubernetes 出口调用流程?
- ssis - SSIS 面临身份验证失败,因为远程方已关闭传输流-异常
- android - 在寻找匹配的'''时猛击意外的EOF
- shopify - 如何使用 Shopify API 创建结帐
- php - 请求缺少所需的身份验证凭据。预期要刷新的 OAuth 2 访问令牌、登录 cookie 或其他有效身份验证凭据
- linux - echo $(filename) 和 cat 文件名有什么区别?