我正在尝试使用Angular作为前端和java ee Web服务jax rs作为后端将图像上传到服务器。这是我的角度/前端代码:
网页:
<md-card>
<input type="file" (change)="onChange($event)" placeholder="Upload files" >
</md-card>
对于组件:
fileChange(event) {
let fileList: FileList = event.target.files;
let fileListLength = fileList.length;
if(fileListLength > 0) {
let formData:FormData = new FormData();
for (var i = 0; i < fileListLength; i++) {
formData.append("uploadFile[]", fileList[i]);
}
let headers = new Headers();
headers.append('Content-Type', 'multipart/form-data');
headers.append('Accept', 'application/json');
let options = new RequestOptions({ headers: headers });
this.http.post("http://localhost:8080/BCWEB/uploadProdImage", formData, options)
.map(res => res.json())
.catch(error => Observable.throw(error))
.subscribe(
data => console.log('success'),
error => console.log(error)
)
}
}
对于后端 java ee restful Web 服务:
private static final String SERVER_UPLOAD_LOCATION_FOLDER = "C://Users/007EAA/Downloads/tes/";
@POST
@Path("/uploadProdImage")
@Consumes("multipart/form-data")
public Response uploadFile2(MultipartFormDataInput input) {
String fileName = "";
Map<String, List<InputPart>> formParts = input.getFormDataMap();
List<InputPart> inPart = formParts.get("file");
for (InputPart inputPart : inPart) {
try {
// Retrieve headers, read the Content-Disposition header to obtain the original name of the file
MultivaluedMap<String, String> headers = inputPart.getHeaders();
fileName = parseFileName(headers);
// Handle the body of that part with an InputStream
InputStream istream = inputPart.getBody(InputStream.class,null);
fileName = SERVER_UPLOAD_LOCATION_FOLDER + fileName;
saveFile(istream,fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
String output = "File saved to server location : " + fileName;
return Response.status(200).entity(output).build();
}
// Parse Content-Disposition header to get the original file name
private String parseFileName(MultivaluedMap<String, String> headers) {
String[] contentDispositionHeader = headers.getFirst("Content-Disposition").split(";");
for (String name : contentDispositionHeader) {
if ((name.trim().startsWith("filename"))) {
String[] tmp = name.split("=");
String fileName = tmp[1].trim().replaceAll(""","");
return fileName;
}
}
return "randomName";
}
// save uploaded file to a defined location on the server
private void saveFile(InputStream uploadedInputStream,
String serverLocation) {
try {
OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
int read = 0;
byte[] bytes = new byte[1024];
outpuStream = new FileOutputStream(new File(serverLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
outpuStream.write(bytes, 0, read);
}
outpuStream.flush();
outpuStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
问题是请求的资源上不存在"访问控制允许源"标头。因此,不允许访问源"http://localhost:4200"。响应的 HTTP 状态代码为 500。
但是当我尝试在服务器上添加用户时,它会毫无问题地添加,因此这不是服务器问题。谁能帮忙?
问题是您的前端和后端存在于不同的本地主机上,默认情况下,出于安全原因,跨源请求被拒绝。
您需要在测试期间在后端启用跨源请求,并在前端和后端位于同一区域时禁用它用于生产。要启用跨源,您需要添加以下提供商代码段:
package com.yourdomain.package;
import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
@Provider
public class CORSFilter implements ContainerResponseFilter {
@Override
public void filter(final ContainerRequestContext requestContext,
final ContainerResponseContext cres) throws IOException {
cres.getHeaders().add("Access-Control-Allow-Origin", "*");
cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
cres.getHeaders().add("Access-Control-Max-Age", "1209600");
}
}
关于 CORS 的信息
从这个 SO 问题中提取的片段