【问题标题】:Ajax Call ERror Cross Origin REquest: Pulling list of universities for autocomplete in railsAjax Call ERror Cross Origin REquest: Pulling list of university for autocomplete in rails
【发布时间】:2016-09-12 21:46:45
【问题描述】:

我很难理解 Ajax 的概念。我的目标很简单,为一个自动完成的表格提取教育机构列表。目标:用户输入类似“University of Wa”,然后可能会出现“University of Waterloo”。这是我嵌入的 ruby​​ 的样子:

<%= f.text_field :university, :id => "university-field", :onkeydown=>"updateUniSearch()" %>

还有我的javascript:

     function updateUniSearch() {
        /*jQuery UI Autocomplete for University Search Form*/
        $("#university-field").autocomplete({
             dataType: "json",
            source: "http://universities.hipolabs.com",
         async: true,
           crossdomain: true
        });
     };

我在这里找到了一个大学名称列表 API:https://github.com/Hipo/university-domains-list

目前,当我运行我的页面时,我收到以下错误:

    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://universities.hipolabs.com/?term=university. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

我是在正确地做到这一点,还是我已经走远了?同样,我只是想使用自动完成功能来显示来自外部来源的大学列表,而不是试图找到大量大学列表并将它们保存在本地数组或 javascript 中。提前谢谢你。

【问题讨论】:

    标签: javascript jquery ruby-on-rails ajax autocomplete


    【解决方案1】:

    浏览器不允许跨域 Ajax 请求,除非 CSP (Content Sharing Policy) 允许该域或数据源提供 Cross-Origin Resource Sharing (CORS) 标头。

    class ApplicationController
    
      before_action :set_csp, if: { request.format.html? }
    
      private
        def set_csp
          response.headers['Content-Security-Policy'] = "connect-src http://universities.hipolabs.com 'self'"
        end
    end
    

    但是,CSP 和 CORS 是一项相对较新的创新 - 在过去,执行 AJAX 的唯一方法是利用 Same Origin Policy 中的一个漏洞,该漏洞允许从任何域加载脚本。

    这使用的是所谓的 JSONP——你使用 JSON 并将它包装在一个 javascript 函数中。为了让它工作,您调用的 API 必须提供 JSONP 响应。

    很遗憾,http://universities.hipolabs.com/search 不提供 JSONP 响应。

    您通过将脚本标签附加到 DOM 来加载数据 - 加载完成后,它会调用包装 JSON 的回调函数。听起来很愚蠢?是的。幸运的是,您现在很少需要使用 JSONP,因为大多数有价值的 API 都会发送 CORS 标头,并且 CSP 得到了相当广泛的支持。

    因此,您要么只需要依赖 CSP,要么通过自己的服务器代理请求。

    require 'net/http'
    class UniversitiesController < ApplicationController
      def search
        uri = URI("http://universities.hipolabs.com")
        uri.query = URI.encode_www_form(params.permit(:name, :country))
        res = Net::HTTP.get_response(uri)
        if res.is_a?(Net::HTTPSuccess)
          render json: res.body
        else
          head res.code.to_i
        end
      end
    end
    

    或者只是找到一个更好的数据源,使用 CORS 来允许跨域访问。

    【讨论】:

      【解决方案2】:

      出于安全原因,json 的 dataType 不支持跨域请求。试试jsonp(带有填充的JSON)。

      【讨论】:

        猜你喜欢
        • 2021-06-04
        • 1970-01-01
        • 2016-04-11
        • 2013-03-12
        • 2017-03-31
        • 2018-06-29
        • 2021-05-16
        • 2022-12-19
        相关资源
        最近更新 更多