Erro 413 com arquivos acima de 1 MB - resolvido

spring.servlet.multipart.max-file-size=128MB
spring.servlet.multipart.max-request-size=128MB
spring.servlet.multipart.enabled=true

e assim

spring.http.multipart.max-file-size = 20MB
spring.http.multipart.max-request-size = 20MB

O que está de errado ?

Access to XMLHttpRequest at ‘https://crud.movimentoneem.life/crud-api/api/carrousel/’ from origin ‘https://app.movimentoneem.life’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
polyfills-es2015.d868f9f91e9b61395ae1.js:1 POST https://crud.movimentoneem.life/crud-api/api/carrousel/ net::ERR_FAILED 413

Este erro da no console

Alguém já passou por isso ?

É configuração do Spring que está errada ?

Configuração no servidor ?

O content-type da requisição é multipart/form-data?

1 curtida

Testei com um assim:

<form
  [formGroup]="formGroup"
  fxLayout="column"
  fxLayoutGap="8px"
  style="padding: 0px 16px; margin-top: 20px"
  (ngSubmit)="salvar()"
>

e assim:

<form
  [formGroup]="formGroup"
  fxLayout="column"
  fxLayoutGap="8px"
  style="padding: 0px 16px; margin-top: 20px"
  (ngSubmit)="salvar()"
  enctype="multipart/form-data"
>

Os dois deram o mesmo erro.

Como está sendo feita a requisição na função salvar()?

1 curtida

Angular

async salvar(): Promise<void> {
  let httpReturn: any;
  
  try {
    const dto = "dto";
    const filesMultipartFormParam = "file";
    const formData: FormData = new FormData();
    const blob: Blob = new Blob([JSON.stringify(this.entidade)], {
      type: "application/json",
    });
    
    formData.append(dto, blob);
    
    if (this.arquivos !== undefined && this.arquivos !== null) {
      for (let i = 0; i < this.arquivos.length; i++) {
        formData.append(filesMultipartFormParam, this.arquivos[i]);
      }
    }
    
    if (this.formGroup.value.idString) {
      httpReturn = await this.http.put(
        this.environmentBackend + API + this.urlBase + "/" + this.formGroup.value.idString + "/",
        formData
      ).toPromise();
    } else {
      httpReturn = await this.http.post(
        this.environmentBackend + API + this.urlBase + "/", formData
      ).toPromise();
    }
    
    this.toastrService.success(httpReturn["texto"]);
    this.voltar();
  } catch (error: any) {
    this.erroSalvar = true;
    this.errorServiceS.error(error);
  }
}

Java

@ApiOperation("Cadastrar produto")
@PostMapping(consumes = MULTIPART_FORM_DATA_VALUE, produces = APPLICATION_JSON_VALUE)
public ResponseEntity<?> inserir(
  @Valid @RequestPart final ProdutoFormDTO dto, 
  final MultipartFile file, 
  @ApiIgnore final Principal principal
) {
  try {
    service.salvar(dto, null, principal, file);
    return mensagemSalvar();
  } catch (final GeralException e) {
    return erroExceptionComRegra(e, ENTIDADE);
  } catch (final Exception e) {
    return excecaoGeralSalvar(e, ERROR, ENTIDADE, ENTIDADE);
  }
}

Ah rapaiz, e esse erro de CORS? Será que ele tah impedindo algum header que permita o upload funcionar? (é soh um palpite).

1 curtida

O estranho que imagens abaixo de 1mega, passa.

Se for no cors o que pode ser ?

1 curtida

Vc tem razão.


Quando a requisição é enviada, no console do navegador (na aba network), a requisição é realmente enviada como multipart/form-data?

1 curtida

Sim

image

Cors do java

package br.com.ghnetsoft.gestaovendasatendimento.crud.config;

import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Order(HIGHEST_PRECEDENCE)
@Slf4j
@Component
public class SmpleCORSFilter implements Filter {

    @Value("${origens-permitidas}")
    private String[] origensPermitidas;

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        log.info("Sistema de crud | SmpleCORSFilter inicio");
    }

    @Override
    public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain chain) throws IOException, ServletException {
        log.info("doFilter");
        final HttpServletResponse response = (HttpServletResponse) resp;
        final HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
        response.setHeader("Access-Control-Expose-Headers", "Location");
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, response);
        }
    }

    @Override
    public void destroy() {
        //
    }
}

Posta o application.yml ai (a parte onde vc tentou setar as propriedades referentes ao tamanho da requisição e multipart).

1 curtida
###### MULTIPART ######
spring.servlet.multipart.max-file-size=128MB
spring.servlet.multipart.max-request-size=128MB

Estranho, que parece estar certo, mas não está né

Pode ser algo no servidor se sim, o que pode ser ?

Porque em homologação funciona.

Em outro ambiente funciona com arquivos acima de 1MB então?

Estava dando uma lida aqui para ver se encontrava algo, mas parece que está certo sua configuração. Vc usa o tomcat para subir o projeto? E qual a versão do spring-boot?

1 curtida

No ambiente de homologação funciona.

spring-2.3.5.RELEASE

start.sh está assim

#!/bin/bash

PORT="8080"
LOG_FILE="/var/log/gestaovendas.log"
JAR="/usr/local/gestaovendas/gestaovendasatendimentocrud.jar"

java -jar -Dserver.port=$PORT -Dspring.profiles.active=prod $JAR >> $LOG_FILE

De homolgação está assim

FROM adoptopenjdk/openjdk11:jre-11.0.9_11.1-alpine
VOLUME [ "/tmp" ]

RUN apk add --no-cache tzdata
ENV TZ America/Sao_Paulo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY *.jar app.jar

ENTRYPOINT ["sh", "-c", "exec java -jar app.jar  -Dfile.encoding=UTF-8 --spring.profiles.active=hom"]

Eita, então esse erro soh acontece no ambiente de produção? Quando vc roda local, funciona?

1 curtida

Local e ambiente de homologação funcionam

Acho que tu pode colocar um log no endpoint que imprima todos os headers da requisição que estão chegando. E também investigar se realmente as propriedades de multipart que aumentam o limite do upload estão realmente sendo aplicadas em produção (tu consegue imprimir elas no log usando o @Value).

1 curtida