【问题标题】:Is it possible to send http calls via grunt connect?是否可以通过 grunt connect 发送 http 调用?
【发布时间】:2018-03-25 14:56:31
【问题描述】:

我有一个 Web 应用程序,其前端基于 Angular 和后端作为 Spring Rest API。我使用 grunt connect 为前端提供服务,而其余 api 运行在 localhst:8080 上,grunt 服务器运行在 localhost:9002 上。 因此,从角度来看,当我使用 angular-resource 向后端服务器发送 http 调用时,出现以下错误:

Failed to load localhost:8080/api/v1/user: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https

angular.js:14800 Possibly unhandled rejection: {"data":null,"status":-1,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"localhost:8080/api/v1/user","data":{"user":{"email":"a","password":"a"}},"headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json;charset=utf-8"}},"statusText":"","xhrStatus":"error","resource":{"user":"..."}}

JS 文件:

angular.module('userModule').factory('userService',function($resource){
  var dataResource = $resource('user',{},
    {

      saveUser :{
        method: 'POST',
        url:'localhost:8080/api/v1/user',
        params : '@user'  
      },

    });
    return dataResource;

});

Gruntfile

'use strict';

module.exports = function (grunt) {
  var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  var serveStatic = require('serve-static');

  // Define the configuration for all the tasks
  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    clean: ["dist"],

    htmlmin: {                                     // Task
      dist: {                                      // Target
        options: {                                 // Target options
          removeComments: true,
          collapseWhitespace: true
        },
        files: {                                   // Dictionary of files
          'dist/index.html': 'dist/index.html'     // 'destination': 'source'
        }
      }
    },

    copy: {
      main: {
        expand: true,
        cwd: '.',
        src: ['**', /* '!js/**', '!lib/**', */ '!**/*.css', '!node_modules/**', '!Gruntfile.js', '!package.json', '!package-lock.json'],
        dest: 'dist/'
      },
      fonts: {
        expand: true,
        cwd: 'lib/fonts',
        src: ['**'],
        dest: 'dist/fonts'
      }
    },

    rev: {
      files: {
        src: ['dist/**/*.{js,css}', '!dist/lib/**/*.{js,css}', '!dist/js/services/**/*.{js,css}']
      }
    },

    useminPrepare: {
      html: 'index.html'
    },

    usemin: {
      html: ['dist/index.html']
    },

    uglify: {
      options: {
        report: 'min',
        mangle: false
      }
    },

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      js: {
        files: ['js/*.js'],
        options: {
          livereload: '<%= connect.options.livereload %>'
        }
      },
      styles: {
        files: ['css/*.css']
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '*.html',
          'css/*.css',
          'images/*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: 9002,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: '0.0.0.0',
        livereload: 35730,
        base: '.',
        middleware: function (connect, options, middlewares) {
            middlewares.unshift(function (req, res, next) {
                res.setHeader('Access-Control-Allow-Origin', '*');
                res.setHeader('Access-Control-Allow-Methods', '*');
                return next();

            });

            return middlewares;
        }

      },

      proxies: [
        {
          context: '/api/v1',
          host: 'localhost',
          port: 8080,
          changeOrigin: true
        }
      ],
      livereload: {
        options: {
          open: false,
          middleware: function (connect) {
            return [
              proxySnippet,
              serveStatic('.')
            ];
          }
        }
      }
    },
  });

  grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
    grunt.task.run([
      'configureProxies',
      'connect:livereload',
      'watch'
    ]);
  });

  grunt.registerTask('default', [
    'clean', 'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'rev', 'usemin', 'htmlmin'
  ]);

};

有人可以告诉我是否可以使用 grunt connect 发送 http 调用?

【问题讨论】:

    标签: angularjs gruntjs angular-resource grunt-contrib-connect


    【解决方案1】:

    您遇到了 CORS 问题,当您向不同的域或架构 http https 或不同的端口发出请求时会发生这种情况(您的情况属于这种情况)。有两种选择。

    1. 在您的后端服务器(在您的情况下是弹簧支持的服务器)上允许 CORS。

      @EnableWebSecurity
      public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
      
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http
              // by default uses a Bean by the name of corsConfigurationSource
              .cors().and()
              ...
          }
      
          @Bean
          CorsConfigurationSource corsConfigurationSource() {
              CorsConfiguration configuration = new CorsConfiguration();
              configuration.setAllowedOrigins(Arrays.asList("http://localhost:8080"));
              configuration.setAllowedMethods(Arrays.asList("GET","POST"));
              UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
              source.registerCorsConfiguration("/**", configuration);
              return source;
          }
      }
      

      更多信息可以在here找到。

    2. 在同一个完整的 HTTP 服务器(如 apache、nginx)中配置前端和后端,并如下设置请求处理。

      一个。在默认路径上提供所有静态/角度资源。 (localhost/)
      b。将您的所有后端请求发送到 localhost/api/ 并将其代理到您的后端 localhost:8080/api 应用程序。

      Nginx 示例:

      server {
          listen 80;
      
          # The host name to respond to
          server_name localhost;
      
          location /api/ {
              # Backend nodejs server
              proxy_pass          http://localhost:8080/api;
              proxy_http_version  1.1;
              proxy_set_header    Upgrade     $http_upgrade;
              proxy_set_header    Connection  $connection_upgrade;
          }
      
          location / {
              root /angular directory path/; 
          }
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多