Можно ли отправлять http звонки через grunt connect?

У меня есть веб-приложение с внешним интерфейсом, основанным на угловом и заднем конце, в качестве API пружинного упора. Я использую Grunt Connect, чтобы обслуживать интерфейс, в то время как остальные API работает localhst:8080сервер grunt работает на localhost:9002, Итак, из angular, когда я отправляю http-вызов на внутренний сервер с помощью angular-resource, я получаю следующую ошибку:

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'
  ]);

};

Может кто-нибудь сказать мне, возможно ли отправлять http-вызовы с помощью grunt 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;
        }
    }
    

    Дополнительную информацию можно найти здесь.

  2. Сконфигурируйте Front end и backend в том же полноценном HTTP-сервере, как apache, nginx и настройте обработку запросов, как показано ниже.

    а. Обслуживайте все статические / угловые ресурсы по пути по умолчанию. (localhost/)
    б) Отправьте все свои запросы на бэкэнд 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/; 
        }
    }
    
Другие вопросы по тегам