无法使用内容类型发布:从角度到轨道的应用程序/json

Posted

技术标签:

【中文标题】无法使用内容类型发布:从角度到轨道的应用程序/json【英文标题】:Cannot POST with content-type: application/json from angular to rails 【发布时间】:2017-10-29 00:44:12 【问题描述】:

所以我尝试使用 Content-Type: application/json 从 Angular 向我的 Rails 后端发送 POST 请求。我在控制台中收到以下错误:

angular.js:12578 选项http://localhost:3000/api/student_create 404(未找到)

XMLHttpRequest 无法加载 http://localhost:3000/api/student_create。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'http://localhost:8008' 不允许访问。响应的 HTTP 状态代码为 404。

请注意,当我使用Content-Type: application/x-www-form-urlencoded 时,post 请求可以正常工作

它也可以在 Postman 中使用,在 header 中设置 application/json Content-Type。

角度控制器:

.controller('View1Ctrl', function($scope, $http) 

  var data = 
    name: "name"
  ;
  $http(
    url: 'http://localhost:3000/api/student_create',
    dataType: 'json',
    method: 'POST',
    data:data,
    headers: 
      "Accept": "application/json",
      "Content-Type": "application/json",
      "Access-Control-Allow-Origin": "*"
    
  ).then(function(response) 
    console.log(response)
  , function(error) 
    console.log(error)
  );

);

API 控制器(Rails):

class ApiController < ApplicationController
     before_action :set_headers
     skip_before_action :verify_authenticity_token

  def set_headers
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT'
    headers['Access-Control-Request-Method'] = '*'
    headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
    end
  def create_student
    student = StudentUser.new
    student.name= params[:name]
    student.save
    render json: "test".to_json #temporary
  end

路线:post 'api/student_create' =&gt; 'api#create_student'

编辑:前端在 http://localhost:8008,后端在 localhost:3000

【问题讨论】:

您要发布的数据的大小是多少? 只是文字。 (角度控制器中的data 对象) 你能验证你发送的对象是一个有效的json对象吗 @alphapilgrim 是的,它是有效的,它只是 data 对象 Rails 代码需要一个路由来响应使用 CORS 标头的 OPTIONS 请求。 【参考方案1】:

您好,我在使用 Rails 与 Angular 交互时也遇到了这个问题。 经过大量研究后,我发现了解决此问题的 gem 'rack-cors'。您可以关注其文档here。默认情况下,Rails 不允许跨源资源共享。所以基本上它很好地处理了跨源请求。

步骤:

安装gem:

gem install rack-cors

或者在您的 Gemfile 中:

gem 'rack-cors', :require => 'rack/cors'

application.rb 文件

module YourApp
  class Application < Rails::Application

    # ...

    # Rails 3/4

    config.middleware.insert_before 0, "Rack::Cors" do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

    # Rails 5

    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

  end
end

【讨论】:

【参考方案2】:

尝试以下操作,来自How to Configure CORS Accept Headers in Rails API Application

因此,即使您的消费者在“localhost:3000”上并且您的提供者在“localhost:3001”上,除非您的 Web 服务设置了允许的 CORS 策略,否则响应将被忽略。此策略由提供商在 HTTP 响应中设置特定的 CORS 标头来定义,消费者应用程序(例如浏览器)注定要强制执行。例如,配置这些标头:

# in config / application.rb
config.action_dispatch.default_headers = 
  'Access-Control-Allow-Origin' => 'http://my-web-service-consumer-site.com',
  'Access-Control-Request-Method' => % w 
    GET POST OPTIONS
  .join(",")

每个站点:

请注意,强烈建议不要设置 'Access-Control-Allow-Origin' => '*',除非您提供的公共 API 可供任何消费者访问。强>

【讨论】:

你可以尝试使用dataType: 'jsonp'。尝试搜索如何实现jsonp进行跨域ajax调用。

以上是关于无法使用内容类型发布:从角度到轨道的应用程序/json的主要内容,如果未能解决你的问题,请参考以下文章

在角度js中将值从一个控件传递到另一个控件[重复]

请求的资源上不存在“Access-Control-Allow-Origin”标头:角度和轨道

从 Android 的 ScrollView 中删除滚动条轨道

从两个角度理解为什么 JS 中没有函数重载

如何使用 JWT 从前端(角度 4)将密钥传递到后端(节点 js)

无法将范围变量绑定到角度js中的html元素