Программа выбрасывает заголовок "Access-Control-Allow-Origin" в JavaScript? Работает в Почтальоне, а не через браузер
решаемая
Я работаю над этой программой с 07:00. Это сводит меня с ума. Я написал несколько веб-приложений с полным стеком, и у меня не было этой проблемы.
В основном у меня есть форма в HTML, которая позволяет пользователю вводить данные. При каждом нажатии кнопки отправки эти данные отправляются в коллекцию в mongoDB. Я проверил это в почтальоне, и это работает. Однако, когда я запускаю программу через веб-браузер, я получаю эту ошибку:
XMLHttpRequest не может загрузить http://localhost:8080/articles/addArticle. В запрошенном ресурсе отсутствует заголовок "Access-Control-Allow-Origin". Происхождение 'null', следовательно, не разрешено. Ответ имел HTTP-код состояния 404.
Я попытался установить CORS и настроить конечную точку
Я попытался зайти в файл javascript и изменить
Это мой файл JavaScript
alert('JS is linked to page!');
function Article(id = 1, title = "", authors="", content = "", genre = "", date = 1497484623) {
console.log("JavaScript file loaded successfully");
var self = this;
self.Id = id;
self.Title = title;
self.Authors = authors;
self.Content = content;
self.Genre = genre;
self.Date = date;
self.Save = function() {
var settings = {
url: 'http://localhost:8080/articles/addArticle',
method: 'POST',
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "application/json");
}
};
var myData = {
"Id" : self.Id,
"Title": self.Title,
"Authors": self.Authors,
"Content": self.Content,
"Genre": self.Genre,
"Date": self.Date
};
settings.data = myData;
$.ajax(settings).done(function(article) {
var myArticle = new Article(article.Id, article.Title, article.Authors,
article.Content, article.Genre, article.Date);
});
};
}
function addArticle(Article) {
alert('addArticle Activated');
var settings = {
url: 'http://localhost:8080/articles/addArticle',
method: 'POST',
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "application/json");
}
};
var myData = {
"Title": Article.Title,
"Authors" : Article.Authors,
"Content": Article.Content,
"Genre" : Article.Genre,
"Date": Article.Date
};
settings.data = myData;
$.ajax(settings).done(function(Article) {
var myArticle = new Article(article.Id, article.Title, article.Authors, article.Content,
article.Genre, article.Date);
console.log("Article Created");
});
}
$(document).ready(function() {
$(document).on("submit", "#add-article", function(e) {
e.preventDefault();
alert('submit Activated');
var title, authors, genre, content;
title = $("#Title").val();
director = $("#Authors").val();
rating = $("#Genre").val();
notes = $("#Content").val();
var myArticle = new Article(0, title, authors, genre, content, 1497484623);
alert(myArticle.Title);
addArticle(myArticle);
$("#add-article")[0].reset();
$("#title").focus();
});
});
/*function CreateSuccessRow(Article) {
var successDataRow = `<tr id="Article-${Article.Id}"><td>${Article.Title}</td>
<td>${Article.Authors}</td>
<td>${Article.Genre}</td>
Из-за широкого спроса это код на стороне сервера:
package com.stereoscopics.app.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.stereoscopics.app.models.Article;
import com.stereoscopics.app.repo.ArticleRepo;
@RestController
@RequestMapping("/articles")
public class ArticleController {
private ArticleRepo articleRepo;
@Autowired
public ArticleController(ArticleRepo articleRepo) {
this.articleRepo = articleRepo;
}
@RequestMapping(value = "/findall", method = RequestMethod.GET)
@ResponseBody
public List<Article> findall() {
return articleRepo.findAll();
}
@RequestMapping(value = "/addArticle", method = RequestMethod.POST)
@ResponseBody
public Article addArticle(@RequestBody Article newArticle) {
articleRepo.save(newArticle);
return newArticle;
}
}
Я понятия не имею, как это исправить. Пожалуйста помоги.
ОБНОВИТЬ
Это все еще не работает. Я обновил код в соответствии с некоторыми предложениями, и я либо делаю это неправильно, либо это неправильно. Изменения показаны ниже:
@RestController
@RequestMapping("/articles")
public class ArticleController {
private ArticleRepo articleRepo;
@Autowired
public ArticleController(ArticleRepo articleRepo) {
this.articleRepo = articleRepo;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");
}
@RequestMapping(value = "/findall", method = RequestMethod.GET)
@ResponseBody
public List<Article> findall() {
return articleRepo.findAll();
}
@RequestMapping(value = "/addArticle", method = RequestMethod.POST)
@ResponseBody
public Article addArticle(@RequestBody Article newArticle, final
HttpServletResponse response) {
response.addHeader("Access-Control-Allow-Origin", "*");
articleRepo.save(newArticle);
return newArticle;
}
}
ЭТО НЕ РЕШЕНО
4 ответа
Я случайно отметил это как решенное, когда это явно не так.
Включив номер порта в URL Javascript, сервер выдал ошибку, потому что он принял запрос как исходящий из того места, откуда он не должен был прийти. Когда я удаляю номер порта, он не знает, какой порт ударить. По умолчанию должно быть 8080, но я получаю еще одну ошибку.
На сегодняшний день никто не решил эту проблему. Я создавал приложения без этого, и все, кого я спрашивал на работе, думают, что я должен просто использовать весенние формы. В идеале я бы хотел решить проблему, а не просто искать обходные пути.
В основном это говорит о том, что ваш сервис в http://localhost:8080/articles/addArticle
, следует добавить заголовок "Access-Control-Allow-Origin", который может прочитать браузер.
Я столкнулся с подобным сценарием, когда создавал REST API, но вместо установки Cors (версия которого конфликтует с нашей производственной версией сервера), я просто добавил этот заголовок при отправке ответов клиенту запроса.
response.AddHeader("Access-Control-Allow-Origin", "*");
Если вы используете asp.net, то вы можете поместить этот код в Global.asax
под:
protected void Application_BeginRequest(Object sender, EventArgs e) {
var context = HttpContext.Current;
var response = context.Response;
response.AddHeader("Access-Control-Allow-Origin", "*");
}
Если вы используете java/servlet/jsp, то это очень похоже на то, что у вас уже есть доступ к HttpServletResponse response
так что в вашем теле кода, просто сделайте:
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");
//other codes and stuff here...
}
из вашего кода с другой стороны, который использует Spring, вы можете сделать что-то вроде:
@RequestMapping(value = "/addArticle", method = RequestMethod.POST)
@ResponseBody
public Article addArticle(@RequestBody Article newArticle, final HttpServletResponse response) {
response.addHeader("Access-Control-Allow-Origin", "*");
articleRepo.save(newArticle);
return newArticle;
}
Вы не можете решить Cors как конец JavaScript, я имею в виду, проблема в коде вашего сервера.
Cors - это функция безопасности, реализованная браузером, позвольте мне рассказать вам, как она работает.
когда вы запрашиваете сервер, сначала он выбирает метод option, в это время сервер отправляет список разрешенных источников, он может быть один или несколько. Теперь, если ваш локальный домен или какой-либо другой домен отсутствует в этом списке, браузер не выполняет фактический запрос.
Чтобы это исправить, вам нужно настроить фильтр Cors на вашем сервере, вы можете сделать это как
package com.package.filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class SimpleCORSFilter extends GenericFilterBean {
/**
* The Logger for this class.
*/
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
logger.info("> doFilter");
HttpServletResponse response = (HttpServletResponse) resp;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
//response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(req, resp);
logger.info("< doFilter");
}
теперь, если он все еще не работает, вам придется построчно отлаживать его на сервере, что является кодом, и в конце браузера вы можете проверить, есть ли у метода option список разрешенных источников или нет.
Веди свой CORS
Проблема в том, что вам нужно установить crossDomain
первый.
$.ajax({
crossDomain:true
})
Далее вы собираетесь установить xhrFields
в withCredentials
,
$.ajax({
crossDomain:true,
xhrFields: {
withCredentials: true
}
})
В вашем коде это выглядит как следование этой конфигурации настроек.
let settings = {
url: 'http://localhost:8080/articles/addArticle',
method: 'POST',
crossDomain:true,
xhrFields: {
withCredentials: true
}
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "application/json");
}
};