NutzCN Logo
问答 uniapp上传图片使用跨域过滤,无法成功
发布于 1473天前 作者 半夏 1650 次浏览 复制 上一个帖子 下一个帖子
标签:

上传后端代码

@IocBean
@At("/api/common")
@Filters({@By(type = MyCrossOriginFilter.class)})
public class NoTokenCheckController extends BaseController {
    @At("/upload")
    @AdaptBy(type = UploadAdaptor.class, args = "ioc:upload")
    @Ok("json")
    public ApiResult upload(@Param("file") TempFile tmpFile, @Param("fileId") String fileId, HttpServletRequest req) {
        return success();
    }
}

后端报错日志

2020-11-12 14:28:48,109 [WARN][org.nutz.mvc.impl.processor.FailProcessor] - Error@/api/common/upload :
java.lang.RuntimeException: org.nutz.mvc.upload.UploadException: Not POST or PUT, Wrong HTTP method! --> OPTIONS
	at org.nutz.lang.Lang.wrapThrow(Lang.java:185)
	at org.nutz.mvc.upload.UploadAdaptor.getReferObject(UploadAdaptor.java:199)
	at org.nutz.mvc.upload.UploadAdaptor.getReferObject(UploadAdaptor.java:62)
	at org.nutz.mvc.adaptor.AbstractAdaptor.adapt(AbstractAdaptor.java:250)
	at org.nutz.mvc.upload.UploadAdaptor.adapt(UploadAdaptor.java:117)
	at org.nutz.mvc.impl.processor.AdaptorProcessor.process(AdaptorProcessor.java:25)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.ModuleProcessor.process(ModuleProcessor.java:123)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.EncodingProcessor.process(EncodingProcessor.java:27)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor.process(UpdateRequestAttributesProcessor.java:15)
	at org.nutz.mvc.impl.NutActionChain.doChain(NutActionChain.java:44)
	at org.nutz.mvc.impl.ActionInvoker.invoke(ActionInvoker.java:67)
	at org.nutz.mvc.ActionHandler.handle(ActionHandler.java:31)
	at org.nutz.mvc.NutFilter.doFilter(NutFilter.java:202)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

前端上传的是使用uniapp的uView框架 简易代码如下

<template>
	<u-upload :action="action" ></u-upload>
</template>
<script>
	export default {
		data() {
			return {
				action: 'http://127.0.0.1:8080/api/common/upload'
			}
		}
	}
</script>

前端报错日志

Access to XMLHttpRequest at 'http://127.0.0.1:8080/api/common/upload' from origin 'http://127.0.0.1:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

14 回复
@IocBean
@At("/api/common")

public class NoTokenCheckController extends BaseController {
        @Filters({@By(type = MyCrossOriginFilter.class)})
       @At(value="/upload", methods="OPTIONS")
       public ApiResult uploadXXX(){}

    @At("/upload")
    @AdaptBy(type = UploadAdaptor.class, args = "ioc:upload")
    @Ok("json")
    public ApiResult upload(@Param("file") TempFile tmpFile, @Param("fileId") String fileId, HttpServletRequest req) {
        return success();
    }
}

跨域有点麻烦... 稍微适应一下...

你好,这种方式都试过了,方法上面加,类上面加,还试过在方法上加上@POST注解,会有不同的报错
加上POST注解后,后端请求没有响应前端报错如下

Access to XMLHttpRequest at 'http://127.0.0.1:8080/api/common/upload' from origin 'http://127.0.0.1:8081' has been blocked by CORS policy: Request header field token is not allowed by Access-Control-Allow-Headers in preflight response.

前端代码如下,这边上传是需要在请求头中token的

<template>
	<u-upload :action="action"  :header="header"></u-upload>
</template>
<script>
	export default {
		data() {
			return {
				action: 'http://127.0.0.1:8080/api/common/upload',
                                header:{"token":this.$http.getTokenStorage()}
			}
		}
	}
</script>

MyCrossOriginFilter 代码如下

public class MyCrossOriginFilter extends CrossOriginFilter {

	private final Log log = Logs.get();
	
	@Override
	public View match(ActionContext ac) {
        HttpServletResponse resp = ac.getResponse();
        if (!Strings.isBlank(origin))
            resp.setHeader("Access-Control-Allow-Origin", origin);
        if (!Strings.isBlank(methods))
            resp.setHeader("Access-Control-Allow-Methods", methods);
        if (!Strings.isBlank(headers))
            resp.setHeader("Access-Control-Allow-Headers", "token," + headers);
        if (!Strings.isBlank(credentials))
            resp.setHeader("Access-Control-Allow-Credentials", credentials);
        
        if ("OPTIONS".equals(ac.getRequest().getMethod())) {
            if (log.isDebugEnabled())
                log.debugf("Feedback -- [%s] [%s] [%s] [%s]", origin, methods, headers, credentials);
            return new VoidView();
        }
        
        return null;
    }

这里有上传成功的情况,就是接口加上@POST注解,前端请求不带head参数

按我那样写, 直接贴上, 也是报错吗?

你好,报错,变了不同的报错信息
后端无响应,前端报错如下

Access to XMLHttpRequest at 'http://127.0.0.1:8080/api/common/uploadXXX' from origin 'http://127.0.0.1:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

后端代码如下

@IocBean
@At("/api/common")
public class test extends BaseController {

    @Filters({@By(type = MyCrossOriginFilter.class)})
    @At(value = "/uploadXXX", methods = "OPTIONS")
    public ApiResult uploadXXX() {
        return success();
    }
}

另外,上传时 @AdaptBy(type = UploadAdaptor.class, args = "ioc:upload")这个注解不是必须的吗?

我晕, 你没按我的写啊

我照着你的写了呀,我发帖之前还看了社区上有的跨域报错问题,看到的方法都试了

你写的是

@At(value = "/uploadXXX", methods = "OPTIONS")

我写的是

@At(value = "/upload", methods = "OPTIONS")

嗷嗷嗷, 还有一个事, 不能用ip跨域, 得用localhost或者域名

我看之前的贴子上是说要用127.0.0.1的,我还特意改的,那个/upload有影响吗,就是一个路径名称

用域名比较靠谱, 我印象中ip是不行的

我使用的nutz版本是1.r.65,前端使用的是uniapp
后端接口

@IocBean
@At("/api/test")
public class test extends BaseController {
    @Filters({@By(type = MyCrossOriginFilter.class)})
    @At(value = "/upload", methods = "OPTIONS")
    public ApiResult upload(@Param("file") TempFile tmpFile) {
        return success();
    }

    @Filters({@By(type = MyCrossOriginFilter.class)})
    @At(value = "/upload1", methods = "OPTIONS")
    @AdaptBy(type = UploadAdaptor.class, args = "ioc:upload")
    public ApiResult upload1(@Param("file") TempFile tmpFile) {
        return success();
    }

    @At("/upload2")
    @Filters({@By(type = MyCrossOriginFilter.class)})
    @AdaptBy(type = UploadAdaptor.class, args = "ioc:upload")
    @POST
    public ApiResult upload2(@Param("file") TempFile tmpFile,
                             HttpServletRequest req) {
        return success(FileUtil.saveFile("test", tmpFile));
    }

    @At("/upload3")
    @Filters({@By(type = MyCrossOriginFilter.class)})
    @AdaptBy(type = UploadAdaptor.class, args = "ioc:upload")
    public ApiResult upload3(@Param("file") TempFile tmpFile,
                             HttpServletRequest req) {
        return success(FileUtil.saveFile("test", tmpFile));
    }
}

使用upload2,正常请求可以成功,上传时额外在header上增加token字段,上传失败,报错信息上面有贴出来
其他方式上传都失败,报错信息上面都贴的有

感谢大佬百忙之中查看我的贴子,也有方式能上传成功,我就用这个好了,感谢

添加回复
请先登陆
回到顶部